Skip to content
Snippets Groups Projects
Commit bf9549e6 authored by fangyincheng's avatar fangyincheng
Browse files

Imp:support no request, response and to return nil request, response

parent 19398a55
No related branches found
No related tags found
No related merge requests found
Showing
with 126 additions and 83 deletions
......@@ -81,23 +81,31 @@ func (p *Proxy) Implement(v common.RPCService) {
methodName = "$echo"
}
start := 0
end := len(in)
if in[0].Type().String() == "context.Context" {
start += 1
}
if len(outs) == 1 {
end -= 1
reply = in[len(in)-1]
} else {
if len(outs) == 2 {
if outs[0].Kind() == reflect.Ptr {
reply = reflect.New(outs[0].Elem())
} else {
reply = reflect.New(outs[0])
}
} else {
reply = valueOf
}
if v, ok := in[start].Interface().([]interface{}); ok && end-start == 1 {
start := 0
end := len(in)
if end > 0 {
if in[0].Type().String() == "context.Context" {
start += 1
}
if len(outs) == 1 && in[end-1].Type().Kind() == reflect.Ptr {
end -= 1
reply = in[len(in)-1]
}
}
if end-start <= 0 {
inArr = []interface{}{}
} else if v, ok := in[start].Interface().([]interface{}); ok && end-start == 1 {
inArr = v
} else {
inArr = make([]interface{}, end-start)
......@@ -137,7 +145,6 @@ func (p *Proxy) Implement(v common.RPCService) {
}
f := valueOfElem.Field(i)
if f.Kind() == reflect.Func && f.IsValid() && f.CanSet() {
inNum := t.Type.NumIn()
outNum := t.Type.NumOut()
if outNum != 1 && outNum != 2 {
......@@ -152,12 +159,6 @@ func (p *Proxy) Implement(v common.RPCService) {
continue
}
// reply must be Ptr when outNum == 1
if outNum == 1 && t.Type.In(inNum-1).Kind() != reflect.Ptr {
logger.Warnf("reply type of method %q is not a pointer", t.Name)
continue
}
var funcOuts = make([]reflect.Type, outNum)
for i := 0; i < outNum; i++ {
funcOuts[i] = t.Type.Out(i)
......
......@@ -36,9 +36,10 @@ import (
type TestService struct {
MethodOne func(context.Context, int, bool, *interface{}) error
MethodTwo func([]interface{}, *interface{}) error
MethodTwo func([]interface{}) error
MethodThree func(int, bool) (interface{}, error)
MethodFour func(int, bool) (*interface{}, error) `dubbo:"methodFour"`
MethodFive func() error
Echo func(interface{}, *interface{}) error
}
......@@ -64,19 +65,25 @@ func TestProxy_Implement(t *testing.T) {
p := NewProxy(invoker, nil, map[string]string{constant.ASYNC_KEY: "false"})
s := &TestService{}
p.Implement(s)
err := p.Get().(*TestService).MethodOne(nil, 0, false, nil)
assert.NoError(t, err)
err = p.Get().(*TestService).MethodTwo(nil, nil)
err = p.Get().(*TestService).MethodTwo(nil)
assert.NoError(t, err)
ret, err := p.Get().(*TestService).MethodThree(0, false)
assert.NoError(t, err)
assert.Nil(t, ret) // ret is nil, because it doesn't be injection yet
ret2, err := p.Get().(*TestService).MethodFour(0, false)
assert.NoError(t, err)
assert.Equal(t, "*interface {}", reflect.TypeOf(ret2).String())
err = p.Get().(*TestService).Echo(nil, nil)
assert.NoError(t, err)
err = p.Get().(*TestService).MethodFive()
assert.NoError(t, err)
// inherit & lowercase
p.rpc = nil
type S1 struct {
......@@ -108,24 +115,14 @@ func TestProxy_Implement(t *testing.T) {
p.Implement(s2)
assert.Nil(t, s2.MethodOne)
// reply type
// returns type
p.rpc = nil
type S3 struct {
TestService
MethodOne func(context.Context, []interface{}, struct{}) error
MethodOne func(context.Context, []interface{}, *struct{}) interface{}
}
s3 := &S3{TestService: *s}
p.Implement(s3)
assert.Nil(t, s3.MethodOne)
// returns type
p.rpc = nil
type S4 struct {
TestService
MethodOne func(context.Context, []interface{}, *struct{}) interface{}
}
s4 := &S4{TestService: *s}
p.Implement(s4)
assert.Nil(t, s4.MethodOne)
}
......@@ -268,12 +268,7 @@ func suiteMethod(method reflect.Method) *MethodType {
}
// replyType
if outNum == 1 {
if mtype.In(inNum-1).Kind() != reflect.Ptr {
logger.Errorf("reply type of method %q is not a pointer %v", mname, replyType)
return nil
}
} else {
if outNum == 2 {
replyType = mtype.Out(0)
if !isExportedOrBuiltinType(replyType) {
logger.Errorf("reply type of method %s not exported{%v}", mname, replyType)
......@@ -284,7 +279,7 @@ func suiteMethod(method reflect.Method) *MethodType {
index := 1
// ctxType
if mtype.In(1).String() == "context.Context" {
if inNum > 1 && mtype.In(1).String() == "context.Context" {
ctxType = mtype.In(1)
index = 2
}
......
......@@ -30,12 +30,15 @@ import (
type TestService struct {
}
func (s *TestService) MethodOne(ctx context.Context, args []interface{}, rsp *struct{}) error {
func (s *TestService) MethodOne(ctx context.Context, arg1, arg2, arg3 interface{}) error {
return nil
}
func (s *TestService) MethodTwo(args []interface{}) (struct{}, error) {
func (s *TestService) MethodTwo(arg1, arg2, arg3 interface{}) (interface{}, error) {
return struct{}{}, nil
}
func (s *TestService) MethodThree() error {
return nil
}
func (s *TestService) Service() string {
return "com.test.Path"
}
......@@ -54,15 +57,12 @@ type testService struct {
func (s *testService) Method1(ctx context.Context, args testService, rsp *struct{}) error {
return nil
}
func (s *testService) Method2(ctx context.Context, args []interface{}, rsp struct{}) error {
return nil
}
func (s *testService) Method3(ctx context.Context, args []interface{}) (testService, error) {
func (s *testService) Method2(ctx context.Context, args []interface{}) (testService, error) {
return testService{}, nil
}
func (s *testService) Method4(ctx context.Context, args []interface{}, rsp *struct{}) {
func (s *testService) Method3(ctx context.Context, args []interface{}, rsp *struct{}) {
}
func (s *testService) Method5(ctx context.Context, args []interface{}, rsp *struct{}) *testService {
func (s *testService) Method4(ctx context.Context, args []interface{}, rsp *struct{}) *testService {
return nil
}
func (s *testService) Service() string {
......@@ -92,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,MethodThree,methodTwo", methods)
// repeat
methods, err = ServiceMap.Register("testporotocol", s)
......@@ -144,10 +144,11 @@ func TestSuiteMethod(t *testing.T) {
assert.True(t, ok)
methodType := suiteMethod(method)
method = methodType.Method()
assert.Equal(t, "func(*common.TestService, context.Context, []interface {}, *struct {}) error", method.Type.String())
assert.Equal(t, "func(*common.TestService, context.Context, interface {}, interface {}, interface {}) error", method.Type.String())
at := methodType.ArgsType()
assert.Equal(t, "[]interface {}", at[0].String())
assert.Equal(t, "*struct {}", at[1].String())
assert.Equal(t, "interface {}", at[0].String())
assert.Equal(t, "interface {}", at[1].String())
assert.Equal(t, "interface {}", at[2].String())
ct := methodType.CtxType()
assert.Equal(t, "context.Context", ct.String())
rt := methodType.ReplyType()
......@@ -157,12 +158,25 @@ func TestSuiteMethod(t *testing.T) {
assert.True(t, ok)
methodType = suiteMethod(method)
method = methodType.Method()
assert.Equal(t, "func(*common.TestService, []interface {}) (struct {}, error)", method.Type.String())
assert.Equal(t, "func(*common.TestService, interface {}, interface {}, interface {}) (interface {}, error)", method.Type.String())
at = methodType.ArgsType()
assert.Equal(t, "interface {}", at[0].String())
assert.Equal(t, "interface {}", at[1].String())
assert.Equal(t, "interface {}", at[2].String())
assert.Nil(t, methodType.CtxType())
rt = methodType.ReplyType()
assert.Equal(t, "interface {}", rt.String())
method, ok = reflect.TypeOf(s).MethodByName("MethodThree")
assert.True(t, ok)
methodType = suiteMethod(method)
method = methodType.Method()
assert.Equal(t, "func(*common.TestService) error", method.Type.String())
at = methodType.ArgsType()
assert.Equal(t, "[]interface {}", at[0].String())
assert.Equal(t, 0, len(at))
assert.Nil(t, methodType.CtxType())
rt = methodType.ReplyType()
assert.Equal(t, "struct {}", rt.String())
assert.Nil(t, rt)
// wrong number of in return
s1 := &testService{}
......@@ -177,26 +191,20 @@ func TestSuiteMethod(t *testing.T) {
methodType = suiteMethod(method)
assert.Nil(t, methodType)
// replyType != Ptr
method, ok = reflect.TypeOf(s1).MethodByName("Method2")
assert.True(t, ok)
methodType = suiteMethod(method)
assert.Nil(t, methodType)
// Reply not exported
method, ok = reflect.TypeOf(s1).MethodByName("Method3")
method, ok = reflect.TypeOf(s1).MethodByName("Method2")
assert.True(t, ok)
methodType = suiteMethod(method)
assert.Nil(t, methodType)
// no return
method, ok = reflect.TypeOf(s1).MethodByName("Method4")
method, ok = reflect.TypeOf(s1).MethodByName("Method3")
assert.True(t, ok)
methodType = suiteMethod(method)
assert.Nil(t, methodType)
// return value is not error
method, ok = reflect.TypeOf(s1).MethodByName("Method5")
method, ok = reflect.TypeOf(s1).MethodByName("Method4")
assert.True(t, ok)
methodType = suiteMethod(method)
assert.Nil(t, methodType)
......
......@@ -102,6 +102,13 @@ func main() {
}
println("response result: %v", user)
println("\n\n\nstart to test dubbo - GetUser3")
err = userProvider.GetUser3()
if err != nil {
panic(err)
}
println("succ!")
println("\n\n\nstart to test dubbo - getErr")
user = &User{}
err = userProvider.GetErr(context.TODO(), []interface{}{"A003"}, user)
......
......@@ -103,7 +103,8 @@ type UserProvider struct {
GetUser func(ctx context.Context, req []interface{}, rsp *User) error
GetUser0 func(id string, name string) (User, error)
GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error
GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"`
GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"`
GetUser3 func() error
Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
}
......
......@@ -25,12 +25,12 @@ import (
)
import (
"github.com/dubbogo/hessian2"
perrors "github.com/pkg/errors"
)
import (
"github.com/apache/dubbo-go/config"
hessian "github.com/dubbogo/hessian2"
)
type Gender hessian.JavaEnum
......@@ -130,14 +130,6 @@ 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
......@@ -153,10 +145,6 @@ func (u *UserProvider) GetUser(ctx context.Context, req []interface{}, rsp *User
return err
}
func (u *UserProvider) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
return hessian.NewThrowable("exception")
}
func (u *UserProvider) GetUser0(id string, name string) (User, error) {
var err error
......@@ -171,6 +159,22 @@ 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.Itoa(int(req[0].(int32)))
return err
}
func (u *UserProvider) GetUser3() error {
return nil
}
func (u *UserProvider) GetErr(ctx context.Context, req []interface{}, rsp *User) error {
return hessian.NewThrowable("exception")
}
func (u *UserProvider) GetUsers(req []interface{}) ([]interface{}, error) {
var err error
......
......@@ -55,6 +55,8 @@ public class Consumer {
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());
userProvider.GetUser3();
System.out.println("GetUser3 succ");
User user9 = userProvider.GetUser1("A003");
} catch (Exception e) {
......
......@@ -23,7 +23,7 @@ public interface UserProvider {
User GetErr(String userId) throws Exception;
User GetUser1(String userId);
User getUser(int usercode);
void GetUser3();
List<User> GetUsers(List<String> userIdList);
User GetUser0(String userId, String name);
}
......@@ -12,6 +12,8 @@ public interface UserProvider {
List<User> GetUsers(List<String> userIdList);
void GetUser3();
User GetUser0(String userId, String name);
User GetErr(String userId) throws Exception;
......
......@@ -35,6 +35,8 @@ public class UserProviderAnotherImpl implements UserProvider {
public User GetUser0(String userId, String name) {
return new User(userId, name, 48);
}
public void GetUser3() {
}
public User GetErr(String userId) throws Exception {
throw new Exception("exception");
}
......
......@@ -56,6 +56,9 @@ public class UserProviderImpl implements UserProvider {
return userList;
}
public void GetUser3() {
}
public Map<String, User> GetUserMap(List<String> userIdList) {
Iterator it = userIdList.iterator();
Map<String, User> map = new HashMap<String, User>();
......
......@@ -94,6 +94,13 @@ func main() {
}
println("response result: %v", user)
println("\n\n\nstart to test jsonrpc - GetUser3")
err = userProvider.GetUser3()
if err != nil {
panic(err)
}
println("succ!")
println("\n\n\nstart to test jsonrpc illegal method")
err = userProvider.GetUser1(context.TODO(), []interface{}{"A003"}, user)
if err != nil {
......
......@@ -54,7 +54,8 @@ type UserProvider struct {
GetUser0 func(id string, name string) (JsonRPCUser, error)
GetUser1 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
GetUser2 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error `dubbo:"getUser"`
Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
GetUser3 func() error
Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
}
func (u *UserProvider) Service() string {
......
......@@ -137,6 +137,10 @@ func (u *UserProvider) GetUser2(ctx context.Context, req []interface{}, rsp *Use
return err
}
func (u *UserProvider) GetUser3() error {
return nil
}
func (u *UserProvider) GetUsers(req []interface{}) ([]User, error) {
var err error
......
......@@ -59,6 +59,9 @@ public class Consumer {
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());
userProvider.GetUser3();
System.out.println("GetUser3 succ");
} catch (Exception e) {
e.printStackTrace();
}
......
......@@ -21,7 +21,7 @@ import java.util.List;
public interface UserProvider {
User GetUser(String userId);
User getUser(int usercode);
void GetUser3();
List<User> GetUsers(List<String> userIdList);
User GetUser0(String userId, String name);
}
......@@ -14,6 +14,8 @@ public interface UserProvider {
User GetUser0(String userId, String name);
void GetUser3();
Map<String, User> GetUserMap(List<String> userIdList);
User getUser(int usercode);
......
......@@ -32,9 +32,12 @@ public class UserProviderAnotherImpl implements UserProvider {
return new User(userId, "Joe", 48);
}
public User GetUser0(String userId, String name) {
return new User(userId, name, 48);
}
public User GetUser0(String userId, String name) {
return new User(userId, name, 48);
}
public void GetUser3() {
}
public List<User> GetUsers(ArrayList<String> userIdList) {
Iterator it = userIdList.iterator();
......
......@@ -78,7 +78,8 @@ public class UserProviderImpl implements UserProvider {
public Map<String, User> queryAll() {
return userMap;
}
public void GetUser3() {
}
public User getUser(int userCode) {
return new User(String.valueOf(userCode), "userCode get", 48);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment