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

Imp:modify calling mode of client

parent afa419fe
No related branches found
No related tags found
No related merge requests found
......@@ -54,28 +54,59 @@ func (p *Proxy) Implement(v common.RPCService) {
makeDubboCallProxy := func(methodName string, outs []reflect.Type) func(in []reflect.Value) []reflect.Value {
return func(in []reflect.Value) []reflect.Value {
var (
err error
inv *invocation_impl.RPCInvocation
err error
inv *invocation_impl.RPCInvocation
inArr []interface{}
reply reflect.Value
)
if methodName == "Echo" {
methodName = "$echo"
}
if len(in) == 2 {
inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, in[0].Interface().([]interface{}), in[1].Interface(), p.callBack, common.URL{}, nil)
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 outs[0].Kind() == reflect.Ptr {
reply = reflect.New(outs[0].Elem())
} else {
reply = reflect.New(outs[0])
}
}
if len(in) == 3 {
inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, in[1].Interface().([]interface{}), in[2].Interface(), p.callBack, common.URL{}, nil)
if v, ok := in[start].Interface().([]interface{}); ok && end-start == 1 {
inArr = v
} else {
inArr = make([]interface{}, end-start)
index := 0
for i := start; i < end; i++ {
inArr[index] = in[i].Interface()
index++
}
}
for k, v := range p.attachments {
inv.SetAttachments(k, v)
inv = invocation_impl.NewRPCInvocationForConsumer(methodName, nil, inArr, reply.Interface(), p.callBack, common.URL{}, nil)
for k, value := range p.attachments {
inv.SetAttachments(k, value)
}
result := p.invoke.Invoke(inv)
err = result.Error()
log.Info("[makeDubboCallProxy] err: %v", err)
return []reflect.Value{reflect.ValueOf(&err).Elem()}
log.Info("[makeDubboCallProxy] result: %v, err: %v", result.Result(), err)
if len(outs) == 1 {
return []reflect.Value{reflect.ValueOf(&err).Elem()}
}
if len(outs) == 2 && outs[0].Kind() != reflect.Ptr {
return []reflect.Value{reply.Elem(), reflect.ValueOf(&err).Elem()}
}
return []reflect.Value{reply, reflect.ValueOf(&err).Elem()}
}
}
......@@ -88,35 +119,31 @@ func (p *Proxy) Implement(v common.RPCService) {
}
f := valueOfElem.Field(i)
if f.Kind() == reflect.Func && f.IsValid() && f.CanSet() {
if t.Type.NumIn() != 2 && t.Type.NumIn() != 3 {
log.Warn("method %s of mtype %v has wrong number of in parameters %d; needs exactly 3/4",
t.Name, t.Type.String(), t.Type.NumIn())
continue
}
inNum := t.Type.NumIn()
outNum := t.Type.NumOut()
if t.Type.NumIn() == 2 && t.Type.In(1).Kind() != reflect.Ptr {
log.Warn("reply type of method %q is not a pointer %v", t.Name, t.Type.In(1))
if outNum != 1 && outNum != 2 {
log.Warn("method %s of mtype %v has wrong number of in out parameters %d; needs exactly 1/2",
t.Name, t.Type.String(), outNum)
continue
}
if t.Type.NumIn() == 3 && t.Type.In(2).Kind() != reflect.Ptr {
log.Warn("reply type of method %q is not a pointer %v", t.Name, t.Type.In(2))
// The latest return type of the method must be error.
if returnType := t.Type.Out(outNum - 1); returnType != typError {
log.Warn("the latest return type %s of method %q is not error", returnType, t.Name)
continue
}
// Method needs one out.
if t.Type.NumOut() != 1 {
log.Warn("method %q has %d out parameters; needs exactly 1", t.Name, t.Type.NumOut())
continue
}
// The return type of the method must be error.
if returnType := t.Type.Out(0); returnType != typError {
log.Warn("return type %s of method %q is not error", returnType, t.Name)
// reply must be Ptr when outNum == 1
if outNum == 1 && t.Type.In(inNum-1).Kind() != reflect.Ptr {
log.Warn("reply type of method %q is not a pointer or interface", t.Name)
continue
}
var funcOuts = make([]reflect.Type, t.Type.NumOut())
funcOuts[0] = t.Type.Out(0)
var funcOuts = make([]reflect.Type, outNum)
for i := 0; i < outNum; i++ {
funcOuts[i] = t.Type.Out(i)
}
// do method proxy here:
f.Set(reflect.MakeFunc(f.Type(), makeDubboCallProxy(methodName, funcOuts)))
......
......@@ -3,6 +3,7 @@ package proxy
import (
"context"
"errors"
"reflect"
"testing"
)
......@@ -17,10 +18,11 @@ import (
)
type TestService struct {
MethodOne func(context.Context, []interface{}, *struct{}) error
MethodTwo func([]interface{}, *struct{}) error
MethodThree func([]interface{}, *struct{}) error `dubbo:"methodThree"`
Echo func([]interface{}, *struct{}) error
MethodOne func(context.Context, int, bool, *interface{}) error
MethodTwo func([]interface{}, *interface{}) error
MethodThree func(int, bool) (interface{}, error)
MethodFour func(int, bool) (*interface{}, error) `dubbo:"methodFour"`
Echo func(interface{}, *interface{}) error
}
func (s *TestService) Service() string {
......@@ -45,12 +47,16 @@ 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, nil, nil)
err := p.Get().(*TestService).MethodOne(nil, 0, false, nil)
assert.NoError(t, err)
err = p.Get().(*TestService).MethodTwo(nil, nil)
assert.NoError(t, err)
err = p.Get().(*TestService).MethodThree(nil, nil)
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)
......@@ -58,13 +64,13 @@ func TestProxy_Implement(t *testing.T) {
p.rpc = nil
type S1 struct {
TestService
methodOne func(context.Context, []interface{}, *struct{}) error
methodOne func(context.Context, interface{}, *struct{}) error
}
s1 := &S1{TestService: *s, methodOne: func(i context.Context, i2 []interface{}, i3 *struct{}) error {
s1 := &S1{TestService: *s, methodOne: func(i context.Context, i2 interface{}, i3 *struct{}) error {
return errors.New("errors")
}}
p.Implement(s1)
err = s1.MethodOne(nil, nil, nil)
err = s1.MethodOne(nil, 0, false, nil)
assert.NoError(t, err)
err = s1.methodOne(nil, nil, nil)
assert.EqualError(t, err, "errors")
......@@ -75,21 +81,21 @@ func TestProxy_Implement(t *testing.T) {
p.Implement(&it)
assert.Nil(t, p.rpc)
// args number
// return number
p.rpc = nil
type S2 struct {
TestService
MethodOne func([]interface{}) error
MethodOne func([]interface{}) (*struct{}, int, error)
}
s2 := &S2{TestService: *s}
p.Implement(s2)
assert.Nil(t, s2.MethodOne)
// returns number
// reply type
p.rpc = nil
type S3 struct {
TestService
MethodOne func(context.Context, []interface{}, *struct{}) (interface{}, error)
MethodOne func(context.Context, []interface{}, struct{}) error
}
s3 := &S3{TestService: *s}
p.Implement(s3)
......@@ -105,23 +111,4 @@ func TestProxy_Implement(t *testing.T) {
p.Implement(s4)
assert.Nil(t, s4.MethodOne)
// reply type for number 3
p.rpc = nil
type S5 struct {
TestService
MethodOne func(context.Context, []interface{}, interface{}) error
}
s5 := &S5{TestService: *s}
p.Implement(s5)
assert.Nil(t, s5.MethodOne)
// reply type for number 2
p.rpc = nil
type S6 struct {
TestService
MethodOne func([]interface{}, interface{}) error
}
s6 := &S6{TestService: *s}
p.Implement(s6)
assert.Nil(t, s5.MethodOne)
}
......@@ -52,8 +52,7 @@ func main() {
initProfiling()
gxlog.CInfo("\n\n\necho")
res := ""
err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), []interface{}{"OK"}, &res)
res, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), "OK")
if err != nil {
panic(err)
}
......@@ -69,13 +68,21 @@ func main() {
}
gxlog.CInfo("response result: %v", user)
gxlog.CInfo("\n\n\nstart to test dubbo - GetUser0")
ret, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser0(context.TODO(), "A003")
if err != nil {
panic(err)
}
gxlog.CInfo("response result: %v", ret)
gxlog.CInfo("\n\n\nstart to test dubbo - getUser")
user = &User{}
err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser2(context.TODO(), []interface{}{1}, user)
if err != nil {
fmt.Println("getUser - error: ", err)
} else {
gxlog.CInfo("response result: %v", user)
}
gxlog.CInfo("response result: %v", user)
gxlog.CInfo("\n\n\nstart to test dubbo illegal method")
err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser1(context.TODO(), []interface{}{"A003"}, user)
......
......@@ -77,9 +77,10 @@ func (User) JavaClassName() string {
type UserProvider struct {
GetUser func(ctx context.Context, req []interface{}, rsp *User) error
GetUser0 func(ctx context.Context, req interface{}) (User, error) `dubbo:"GetUser"`
GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error
GetUser2 func(ctx context.Context, req []interface{}, rsp *User) error `dubbo:"getUser"`
Echo func(ctx context.Context, req []interface{}, rsp *string) error // Echo represent EchoFilter will be used
Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
}
func (u *UserProvider) Service() string {
......
......@@ -47,12 +47,12 @@ func main() {
initProfiling()
gxlog.CInfo("\n\n\necho")
res := ""
err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), []interface{}{"OK"}, &res)
res, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).Echo(context.TODO(), "OK")
if err != nil {
fmt.Println("echo - error: ", err)
} else {
gxlog.CInfo("res: %s", res)
}
gxlog.CInfo("res: %s", res)
time.Sleep(3e9)
......@@ -64,13 +64,21 @@ func main() {
}
gxlog.CInfo("response result: %v", user)
gxlog.CInfo("\n\n\nstart to test dubbo - GetUser0")
ret, err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser0(context.TODO(), "A003")
if err != nil {
panic(err)
}
gxlog.CInfo("response result: %v", ret)
gxlog.CInfo("\n\n\nstart to test jsonrpc - getUser")
user = &JsonRPCUser{}
err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser2(context.TODO(), []interface{}{1}, user)
if err != nil {
fmt.Println("getUser - error: ", err)
} else {
gxlog.CInfo("response result: %v", user)
}
gxlog.CInfo("response result: %v", user)
gxlog.CInfo("\n\n\nstart to test jsonrpc illegal method")
err = conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser1(context.TODO(), []interface{}{"A003"}, user)
......
......@@ -31,9 +31,10 @@ func (u JsonRPCUser) String() string {
type UserProvider struct {
GetUser func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
GetUser0 func(ctx context.Context, req interface{}) (*JsonRPCUser, error) `dubbo:"GetUser"`
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{}, rsp *string) error // Echo represent EchoFilter will be used
Echo func(ctx context.Context, req interface{}) (interface{}, error) // Echo represent EchoFilter will be used
}
func (u *UserProvider) Service() string {
......
......@@ -47,9 +47,6 @@ public class Consumer {
e.printStackTrace();
}
try {
EchoService echoService = (EchoService)userProvider;
Object status = echoService.$echo("OK");
System.out.println("echo: "+status);
User user1 = userProvider.GetUser("A003");
System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] " +
" UserInfo, Id:" + user1.getId() + ", name:" + user1.getName() + ", sex:" + user1.getSex().toString()
......
......@@ -19,7 +19,7 @@ func init() {
// RPCService need a Echo method in consumer, if you want to use EchoFilter
// eg:
// Echo func(ctx context.Context, args []interface{}, rsp *Xxx) error
// Echo func(ctx context.Context, arg interface{}, rsp *Xxx) error
type EchoFilter struct {
}
......
......@@ -279,30 +279,18 @@ func (h *RpcServerHandler) callService(req *DubboPackage, ctx context.Context) {
}
// prepare argv
var argv reflect.Value
argIsValue := false // if true, need to indirect before calling.
if method.ArgType().Kind() == reflect.Ptr {
argv = reflect.New(method.ArgType().Elem())
} else {
argv = reflect.New(method.ArgType())
argIsValue = true
}
argvTmp := argv.Interface()
argvTmp = req.Body.(map[string]interface{})["args"] // type is []interface
if argIsValue {
argv = argv.Elem()
}
argv := req.Body.(map[string]interface{})["args"] // type is []interface
// prepare replyv
replyv := reflect.New(method.ReplyType().Elem())
var returnValues []reflect.Value
if method.CtxType() == nil {
returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())})
returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.ValueOf(argv), reflect.ValueOf(replyv.Interface())})
} else {
if contextv := reflect.ValueOf(ctx); contextv.IsValid() {
returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), contextv, reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())})
returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), contextv, reflect.ValueOf(argv), reflect.ValueOf(replyv.Interface())})
} else {
returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.Zero(method.CtxType()), reflect.ValueOf(argvTmp), reflect.ValueOf(replyv.Interface())})
returnValues = method.Method().Func.Call([]reflect.Value{svc.Rcvr(), reflect.Zero(method.CtxType()), reflect.ValueOf(argv), reflect.ValueOf(replyv.Interface())})
}
}
......
......@@ -345,25 +345,6 @@ func serveRequest(ctx context.Context,
return jerrors.New("cannot find method " + methodName + " of svc " + serviceName)
}
// get args
var argv reflect.Value
argIsValue := false
if mtype.ArgType().Kind() == reflect.Ptr {
argv = reflect.New(mtype.ArgType().Elem())
} else {
argv = reflect.New(mtype.ArgType())
argIsValue = true
}
// argv guaranteed to be a pointer now.
argvTmp := argv.Interface()
argvTmp = args
//if err = codec.ReadBody(argv.Interface()); err != nil {
// return jerrors.Trace(err)
//}
if argIsValue {
argv = argv.Elem()
}
replyv := reflect.New(mtype.ReplyType().Elem())
// call service.method(args)
......@@ -374,14 +355,14 @@ func serveRequest(ctx context.Context,
if mtype.CtxType() == nil {
returnValues = mtype.Method().Func.Call([]reflect.Value{
svc.Rcvr(),
reflect.ValueOf(argvTmp),
reflect.ValueOf(args),
reflect.ValueOf(replyv.Interface()),
})
} else {
returnValues = mtype.Method().Func.Call([]reflect.Value{
svc.Rcvr(),
mtype.SuiteContext(ctx),
reflect.ValueOf(argvTmp),
reflect.ValueOf(args),
reflect.ValueOf(replyv.Interface()),
})
}
......
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