Repository: apache/dubbo-go-hessian2
Pull request #218 (2020-08-14 09:13:02)

[refer dubbo 2.7.6] attachment type from map[string]stiring to map[string]interface{} 
1. attachment类型从attachment type from map[string]stiring 到 map[string]interface{} ，和dubbo java对齐
2.功能分成两部分，一部分会在dubbo-go里提交，一部分需要修改hessian.

AlexStocks: @cvictory pls check the travis failure.
cvictory: > @cvictory pls check the travis failure.

找了好久，没找到错误原因啊。
wongoo: > > @cvictory pls check the travis failure.
> 
> 找了好久，没找到错误原因啊。

```
$ go fmt && [[ -z `git status -s` ]]
binary.go
response.go
The command "go fmt && [[ -z `git status -s` ]]" exited with 1.

The command "/tmp/tools/license/license-header-checker -v -a -r -i vendor  /tmp/tools/license/license.txt . go  && [[ -z `git status -s` ]]" exited with 1.

```
codecov-commenter: # [Codecov](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218?src=pr&el=h1) Report
> Merging [#218](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218?src=pr&el=desc) into [master](https://codecov.io/gh/apache/dubbo-go-hessian2/commit/9e91fc9a7de335e427999bd3cd9cd60ef0304169&el=desc) will **increase** coverage by `0.13%`.
> The diff coverage is `76.19%`.

[![Impacted file tree graph](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218/graphs/tree.svg?width=650&height=150&src=pr&token=Yh82j7lS1W)](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #218      +/-   ##
==========================================
+ Coverage   67.03%   67.17%   +0.13%     
==========================================
  Files          24       24              
  Lines        2900     2906       +6     
==========================================
+ Hits         1944     1952       +8     
+ Misses        742      741       -1     
+ Partials      214      213       -1     
```


| [Impacted Files](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [hessian.go](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218/diff?src=pr&el=tree#diff-aGVzc2lhbi5nbw==) | `48.14% <50.00%> (ø)` | |
| [response.go](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218/diff?src=pr&el=tree#diff-cmVzcG9uc2UuZ28=) | `58.17% <66.66%> (+1.80%)` | :arrow_up: |
| [request.go](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218/diff?src=pr&el=tree#diff-cmVxdWVzdC5nbw==) | `61.32% <100.00%> (+0.36%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218?src=pr&el=footer). Last update [9e91fc9...fab853b](https://codecov.io/gh/apache/dubbo-go-hessian2/pull/218?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

cvictory: > > > @cvictory pls check the travis failure.
> > 
> > 
> > 找了好久，没找到错误原因啊。
> 
> ```
> $ go fmt && [[ -z `git status -s` ]]
> binary.go
> response.go
> The command "go fmt && [[ -z `git status -s` ]]" exited with 1.
> 
> The command "/tmp/tools/license/license-header-checker -v -a -r -i vendor  /tmp/tools/license/license.txt . go  && [[ -z `git status -s` ]]" exited with 1.
> ```

发现是有一个文件没有格式化。。

Patch:
diff --git a/hessian.go b/hessian.go
index d4fb135..6527604 100644
--- a/hessian.go
+++ b/hessian.go
@@ -218,7 +218,7 @@ func (h *HessianCodec) ReadBody(rspObj interface{}) error {
 }
 
 // ignore body, but only read attachments
-func (h *HessianCodec) ReadAttachments() (map[string]string, error) {
+func (h *HessianCodec) ReadAttachments() (map[string]interface{}, error) {
 	if h.reader.Buffered() < h.bodyLen {
 		return nil, ErrBodyNotEnough
 	}
@@ -237,7 +237,7 @@ func (h *HessianCodec) ReadAttachments() (map[string]string, error) {
 		if err = unpackRequestBody(NewDecoderWithSkip(buf[:]), rspObj); err != nil {
 			return nil, perrors.WithStack(err)
 		}
-		return rspObj[6].(map[string]string), nil
+		return rspObj[6].(map[string]interface{}), nil
 	case PackageResponse:
 		rspObj := &Response{}
 		if err = unpackResponseBody(NewDecoderWithSkip(buf[:]), rspObj); err != nil {
diff --git a/request.go b/request.go
index 82c1ef5..c668fcb 100644
--- a/request.go
+++ b/request.go
@@ -151,13 +151,13 @@ func getArgsTypeList(args []interface{}) (string, error) {
 
 type Request struct {
 	Params      interface{}
-	Attachments map[string]string
+	Attachments map[string]interface{}
 }
 
 // NewRequest create a new Request
-func NewRequest(params interface{}, atta map[string]string) *Request {
+func NewRequest(params interface{}, atta map[string]interface{}) *Request {
 	if atta == nil {
-		atta = make(map[string]string)
+		atta = make(map[string]interface{})
 	}
 	return &Request{
 		Params:      params,
@@ -327,25 +327,22 @@ func unpackRequestBody(decoder *Decoder, reqObj interface{}) error {
 	}
 	if v, ok := attachments.(map[interface{}]interface{}); ok {
 		v[DUBBO_VERSION_KEY] = dubboVersion
-		req[6] = ToMapStringString(v)
+		req[6] = ToMapStringInterface(v)
 		return nil
 	}
 
 	return perrors.Errorf("get wrong attachments: %+v", attachments)
 }
 
-func ToMapStringString(origin map[interface{}]interface{}) map[string]string {
-	dest := make(map[string]string)
+func ToMapStringInterface(origin map[interface{}]interface{}) map[string]interface{} {
+	dest := make(map[string]interface{})
 	for k, v := range origin {
 		if kv, ok := k.(string); ok {
 			if v == nil {
 				dest[kv] = ""
 				continue
 			}
-
-			if vv, ok := v.(string); ok {
-				dest[kv] = vv
-			}
+			dest[kv] = v
 		}
 	}
 	return dest
diff --git a/response.go b/response.go
index 0b2a97f..910323b 100644
--- a/response.go
+++ b/response.go
@@ -37,13 +37,13 @@ import (
 type Response struct {
 	RspObj      interface{}
 	Exception   error
-	Attachments map[string]string
+	Attachments map[string]interface{}
 }
 
 // NewResponse create a new Response
-func NewResponse(rspObj interface{}, exception error, attachments map[string]string) *Response {
+func NewResponse(rspObj interface{}, exception error, attachments map[string]interface{}) *Response {
 	if attachments == nil {
-		attachments = make(map[string]string)
+		attachments = make(map[string]interface{})
 	}
 	return &Response{
 		RspObj:      rspObj,
@@ -176,7 +176,7 @@ func unpackResponseBody(decoder *Decoder, resp interface{}) error {
 				return perrors.WithStack(err)
 			}
 			if v, ok := attachments.(map[interface{}]interface{}); ok {
-				atta := ToMapStringString(v)
+				atta := ToMapStringInterface(v)
 				response.Attachments = atta
 			} else {
 				return perrors.Errorf("get wrong attachments: %+v", attachments)
@@ -201,7 +201,7 @@ func unpackResponseBody(decoder *Decoder, resp interface{}) error {
 				return perrors.WithStack(err)
 			}
 			if v, ok := attachments.(map[interface{}]interface{}); ok {
-				response.Attachments = ToMapStringString(v)
+				response.Attachments = ToMapStringInterface(v)
 			} else {
 				return perrors.Errorf("get wrong attachments: %+v", attachments)
 			}
@@ -222,7 +222,7 @@ func unpackResponseBody(decoder *Decoder, resp interface{}) error {
 				return perrors.WithStack(err)
 			}
 			if v, ok := attachments.(map[interface{}]interface{}); ok {
-				atta := ToMapStringString(v)
+				atta := ToMapStringInterface(v)
 				response.Attachments = atta
 			} else {
 				return perrors.Errorf("get wrong attachments: %+v", attachments)
@@ -338,8 +338,9 @@ var versionInt = make(map[string]int)
 
 // https://github.com/apache/dubbo/blob/dubbo-2.7.1/dubbo-common/src/main/java/org/apache/dubbo/common/Version.java#L96
 // isSupportResponseAttachment is for compatibility among some dubbo version
-func isSupportResponseAttachment(version string) bool {
-	if version == "" {
+func isSupportResponseAttachment(ver interface{}) bool {
+	version, ok := ver.(string)
+	if !ok || len(version) == 0 {
 		return false
 	}
 
@@ -357,7 +358,11 @@ func isSupportResponseAttachment(version string) bool {
 	return v >= LOWEST_VERSION_FOR_RESPONSE_ATTACHMENT
 }
 
-func version2Int(version string) int {
+func version2Int(ver interface{}) int {
+	version, ok := ver.(string)
+	if !ok || len(version) == 0 {
+		return 0
+	}
 	var v = 0
 	varr := strings.Split(version, ".")
 	length := len(varr)


Test patch:
diff --git a/hessian_test.go b/hessian_test.go
index e466cf2..6f89f0b 100644
--- a/hessian_test.go
+++ b/hessian_test.go
@@ -192,14 +192,14 @@ func TestRequest(t *testing.T) {
 }
 
 func TestHessianCodec_ReadAttachments(t *testing.T) {
+	RegisterPOJO(&AttachObject{})
 	body := &Response{
 		RspObj:      &CaseB{A: "A", B: CaseA{A: "a", B: 1, C: Case{A: "c", B: 2}}},
 		Exception:   nil,
-		Attachments: map[string]string{DUBBO_VERSION_KEY: "2.6.4"},
+		Attachments: map[string]interface{}{DUBBO_VERSION_KEY: "2.6.4", "att": AttachObject{Id: 23, Name: "haha"}},
 	}
 	resp, err := doTestHessianEncodeHeader(t, PackageResponse, Response_OK, body)
 	assert.NoError(t, err)
-
 	unRegisterPOJOs(&CaseB{}, &CaseA{})
 	codecR1 := NewHessianCodec(bufio.NewReader(bytes.NewReader(resp)))
 	codecR2 := NewHessianCodec(bufio.NewReader(bytes.NewReader(resp)))
@@ -214,6 +214,17 @@ func TestHessianCodec_ReadAttachments(t *testing.T) {
 	attrs, err := codecR2.ReadAttachments()
 	assert.NoError(t, err)
 	assert.Equal(t, "2.6.4", attrs[DUBBO_VERSION_KEY])
+	assert.Equal(t, AttachObject{Id: 23, Name: "haha"}, *(attrs["att"].(*AttachObject)))
+	assert.NotEqual(t, AttachObject{Id: 24, Name: "nohaha"}, *(attrs["att"].(*AttachObject)))
 
 	t.Log(attrs)
 }
+
+type AttachObject struct {
+	Id   int32
+	Name string `dubbo:name`
+}
+
+func (AttachObject) JavaClassName() string {
+	return "com.test.Test"
+}
diff --git a/request_test.go b/request_test.go
index 2b7f1f3..37ec48d 100644
--- a/request_test.go
+++ b/request_test.go
@@ -129,7 +129,7 @@ func TestIssue192(t *testing.T) {
 	tests := []struct {
 		name string
 		args args
-		want map[string]string
+		want map[string]interface{}
 	}{
 		{
 			name: "not null",
@@ -140,7 +140,7 @@ func TestIssue192(t *testing.T) {
 					"":  "",
 				},
 			},
-			want: map[string]string{
+			want: map[string]interface{}{
 				"1": "",
 				"2": "3",
 				"":  "",
@@ -149,8 +149,8 @@ func TestIssue192(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if got := ToMapStringString(tt.args.origin); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("ToMapStringString() = %v, want %v", got, tt.want)
+			if got := ToMapStringInterface(tt.args.origin); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("ToMapStringInterface() = %v, want %v", got, tt.want)
 			}
 		})
 	}
diff --git a/response_test.go b/response_test.go
index 7299389..5f0e07a 100644
--- a/response_test.go
+++ b/response_test.go
@@ -168,7 +168,10 @@ func TestCopySlice(t *testing.T) {
 }
 
 func TestIsSupportResponseAttachment(t *testing.T) {
-	is := isSupportResponseAttachment("2.0.10")
+	is := isSupportResponseAttachment("2.X")
+	assert.False(t, is)
+
+	is = isSupportResponseAttachment("2.0.10")
 	assert.False(t, is)
 
 	is = isSupportResponseAttachment("2.5.3")