From 19398a55235a493804838dfa147bf298a5871784 Mon Sep 17 00:00:00 2001
From: fangyincheng <fangyincheng@sina.com>
Date: Tue, 11 Jun 2019 21:12:58 +0800
Subject: [PATCH] Imp:support lowercase function on the provider

---
 common/rpc_service.go                         | 28 +++++++++++++------
 common/rpc_service_test.go                    |  7 ++++-
 examples/dubbo/go-client/app/client.go        | 10 +++----
 examples/dubbo/go-server/app/user.go          | 14 ++++++++++
 .../main/java/com/ikurento/user/Consumer.java |  4 +++
 .../java/com/ikurento/user/UserProvider.java  |  1 +
 examples/jsonrpc/go-client/app/client.go      |  5 ++--
 examples/jsonrpc/go-server/app/user.go        | 16 +++++++++++
 .../main/java/com/ikurento/user/Consumer.java |  4 +++
 .../java/com/ikurento/user/UserProvider.java  |  1 +
 protocol/dubbo/listener.go                    |  6 ++--
 11 files changed, 76 insertions(+), 20 deletions(-)

diff --git a/common/rpc_service.go b/common/rpc_service.go
index d8578a143..2aaa77276 100644
--- a/common/rpc_service.go
+++ b/common/rpc_service.go
@@ -40,6 +40,12 @@ type RPCService interface {
 	Version() string
 }
 
+// for lowercase func
+// func MethodMapper() map[string][string] {
+//     return map[string][string]{}
+// }
+const METHOD_MAPPER = "MethodMapper"
+
 var (
 	// Precompute the reflect type for error. Can't use error directly
 	// because Typeof takes an empty interface value. This is annoying.
@@ -210,20 +216,26 @@ func isExportedOrBuiltinType(t reflect.Type) bool {
 // suitableMethods returns suitable Rpc methods of typ
 func suitableMethods(typ reflect.Type) (string, map[string]*MethodType) {
 	methods := make(map[string]*MethodType)
-	mts := ""
+	var mts []string
 	logger.Debugf("[%s] NumMethod is %d", typ.String(), typ.NumMethod())
+	method, ok := typ.MethodByName(METHOD_MAPPER)
+	var methodMapper map[string]string
+	if ok && method.Type.NumIn() == 1 && method.Type.NumOut() == 1 && method.Type.Out(0).String() == "map[string]string" {
+		methodMapper = method.Func.Call([]reflect.Value{reflect.New(typ.Elem())})[0].Interface().(map[string]string)
+	}
+
 	for m := 0; m < typ.NumMethod(); m++ {
-		method := typ.Method(m)
+		method = typ.Method(m)
 		if mt := suiteMethod(method); mt != nil {
-			methods[method.Name] = mt
-			if m == 0 {
-				mts += method.Name
-			} else {
-				mts += "," + method.Name
+			methodName, ok := methodMapper[method.Name]
+			if !ok {
+				methodName = method.Name
 			}
+			methods[methodName] = mt
+			mts = append(mts, methodName)
 		}
 	}
-	return mts, methods
+	return strings.Join(mts, ","), methods
 }
 
 // suiteMethod returns a suitable Rpc methodType
diff --git a/common/rpc_service_test.go b/common/rpc_service_test.go
index e5bab2c71..9a1e08f71 100644
--- a/common/rpc_service_test.go
+++ b/common/rpc_service_test.go
@@ -42,6 +42,11 @@ func (s *TestService) Service() string {
 func (s *TestService) Version() string {
 	return ""
 }
+func (s *TestService) MethodMapper() map[string]string {
+	return map[string]string{
+		"MethodTwo": "methodTwo",
+	}
+}
 
 type testService struct {
 }
@@ -87,7 +92,7 @@ func TestServiceMap_Register(t *testing.T) {
 	s := &TestService{}
 	methods, err = ServiceMap.Register("testporotocol", s)
 	assert.NoError(t, err)
-	assert.Equal(t, "MethodOne,MethodTwo", methods)
+	assert.Equal(t, "MethodOne,methodTwo", methods)
 
 	// repeat
 	methods, err = ServiceMap.Register("testporotocol", s)
diff --git a/examples/dubbo/go-client/app/client.go b/examples/dubbo/go-client/app/client.go
index fb2d20d3a..954717d16 100644
--- a/examples/dubbo/go-client/app/client.go
+++ b/examples/dubbo/go-client/app/client.go
@@ -93,14 +93,14 @@ func main() {
 	}
 	println("response result: %v", ret1)
 
-	println("\n\n\nstart to test dubbo - getUser2")
+	println("\n\n\nstart to test dubbo - getUser")
 	user = &User{}
-	err = userProvider.GetUser2(context.TODO(), []interface{}{1}, user)
+	var i int32 = 1
+	err = userProvider.GetUser2(context.TODO(), []interface{}{i}, user)
 	if err != nil {
-		println("getUser - error: %v", err)
-	} else {
-		println("response result: %v", user)
+		panic(err)
 	}
+	println("response result: %v", user)
 
 	println("\n\n\nstart to test dubbo - getErr")
 	user = &User{}
diff --git a/examples/dubbo/go-server/app/user.go b/examples/dubbo/go-server/app/user.go
index e4400cc27..953c38bca 100644
--- a/examples/dubbo/go-server/app/user.go
+++ b/examples/dubbo/go-server/app/user.go
@@ -130,6 +130,14 @@ func (u *UserProvider) getUser(userId string) (*User, error) {
 	return nil, fmt.Errorf("invalid user id:%s", userId)
 }
 
+func (u *UserProvider) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
+	var err error
+
+	println("req:%#v", req)
+	rsp.Id = strconv.Itoa(int(req[0].(int32)))
+	return err
+}
+
 func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User) error {
 	var (
 		err  error
@@ -182,6 +190,12 @@ func (u *UserProvider) GetUsers(req []interface{}) ([]interface{}, error) {
 	return []interface{}{user, user1}, err
 }
 
+func (s *UserProvider) MethodMapper() map[string]string {
+	return map[string]string{
+		"GetUser2": "getUser",
+	}
+}
+
 func (u *UserProvider) Service() string {
 	return "com.ikurento.user.UserProvider"
 }
diff --git a/examples/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java b/examples/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java
index f1100e79a..98fa6bdc2 100644
--- a/examples/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java
+++ b/examples/dubbo/java-client/src/main/java/com/ikurento/user/Consumer.java
@@ -51,6 +51,10 @@ public class Consumer {
             System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
                      " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
                      + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
+            User user3 = userProvider.getUser(1);
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                     " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
+                     + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
 
             User user9 = userProvider.GetUser1("A003");
         } catch (Exception e) {
diff --git a/examples/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java b/examples/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
index 036f46332..c7cca9229 100644
--- a/examples/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
+++ b/examples/dubbo/java-client/src/main/java/com/ikurento/user/UserProvider.java
@@ -22,6 +22,7 @@ public interface UserProvider {
 	User GetUser(String userId);
 	User GetErr(String userId) throws Exception;
 	User GetUser1(String userId);
+    User getUser(int usercode);
 
 	List<User> GetUsers(List<String> userIdList);
 	User GetUser0(String userId, String name);
diff --git a/examples/jsonrpc/go-client/app/client.go b/examples/jsonrpc/go-client/app/client.go
index 47d0b6064..ec8bc6dd6 100644
--- a/examples/jsonrpc/go-client/app/client.go
+++ b/examples/jsonrpc/go-client/app/client.go
@@ -90,10 +90,9 @@ func main() {
 	user = &JsonRPCUser{}
 	err = userProvider.GetUser2(context.TODO(), []interface{}{1}, user)
 	if err != nil {
-		println("getUser - error: %v", err)
-	} else {
-		println("response result: %v", user)
+		panic(err)
 	}
+	println("response result: %v", user)
 
 	println("\n\n\nstart to test jsonrpc illegal method")
 	err = userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user)
diff --git a/examples/jsonrpc/go-server/app/user.go b/examples/jsonrpc/go-server/app/user.go
index fbe6f3339..c0beb31d1 100644
--- a/examples/jsonrpc/go-server/app/user.go
+++ b/examples/jsonrpc/go-server/app/user.go
@@ -20,6 +20,7 @@ package main
 import (
 	"context"
 	"fmt"
+	"strconv"
 	"time"
 )
 
@@ -127,6 +128,15 @@ func (u *UserProvider) GetUser0(id string, name string) (User, error) {
 	return *user, err
 }
 
+func (u *UserProvider) GetUser2(ctx context.Context, req []interface{}, rsp *User) error {
+	var err error
+
+	println("req:%#v", req)
+	rsp.Id = strconv.FormatFloat(req[0].(float64), 'f', 0, 64)
+	rsp.Sex = Gender(MAN).String()
+	return err
+}
+
 func (u *UserProvider) GetUsers(req []interface{}) ([]User, error) {
 	var err error
 
@@ -146,6 +156,12 @@ func (u *UserProvider) GetUsers(req []interface{}) ([]User, error) {
 	return []User{*user, *user1}, err
 }
 
+func (s *UserProvider) MethodMapper() map[string]string {
+	return map[string]string{
+		"GetUser2": "getUser",
+	}
+}
+
 func (u *UserProvider) Service() string {
 	return "com.ikurento.user.UserProvider"
 }
diff --git a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java b/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
index b2b8e95f9..f8847fe02 100644
--- a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
+++ b/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/Consumer.java
@@ -55,6 +55,10 @@ public class Consumer {
             System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
                      " UserInfo, Id:" + user2.getId() + ", name:" + user2.getName() + ", sex:" + user2.getSex().toString()
                      + ", age:" + user2.getAge() + ", time:" + user2.getTime().toString());
+            User user3 = userProvider.getUser(1);
+            System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
+                     " UserInfo, Id:" + user3.getId() + ", name:" + user3.getName() + ", sex:" + user3.getSex().toString()
+                     + ", age:" + user3.getAge() + ", time:" + user3.getTime().toString());
         } catch (Exception e) {
             e.printStackTrace();
         }
diff --git a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/UserProvider.java b/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/UserProvider.java
index d5bce8105..255283cad 100644
--- a/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/UserProvider.java
+++ b/examples/jsonrpc/java-client/src/main/java/com/ikurento/user/UserProvider.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 public interface UserProvider {
 	User GetUser(String userId);
+    User getUser(int usercode);
 
 	List<User> GetUsers(List<String> userIdList);
 	User GetUser0(String userId, String name);
diff --git a/protocol/dubbo/listener.go b/protocol/dubbo/listener.go
index ea8c38db9..b2ac981c1 100644
--- a/protocol/dubbo/listener.go
+++ b/protocol/dubbo/listener.go
@@ -268,13 +268,13 @@ func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) {
 		if e := recover(); e != nil {
 			req.Header.ResponseStatus = hessian.Response_SERVER_ERROR
 			if err, ok := e.(error); ok {
-				logger.Errorf("callService panic: %#v", err)
+				logger.Errorf("callService panic: %+v", err)
 				req.Body = perrors.WithStack(err)
 			} else if err, ok := e.(string); ok {
-				logger.Errorf("callService panic: %#v", perrors.New(err))
+				logger.Errorf("callService panic: %+v", perrors.New(err))
 				req.Body = perrors.New(err)
 			} else {
-				logger.Errorf("callService panic: %#v, this is impossible.", e)
+				logger.Errorf("callService panic: %+v, this is impossible.", e)
 				req.Body = e
 			}
 		}
-- 
GitLab