diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java index adbce4e11b2..61e99022963 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java @@ -16,6 +16,8 @@ */ package org.apache.dubbo.rpc.protocol.dubbo.telnet; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.utils.ReflectUtils; import org.apache.dubbo.common.utils.StringUtils; @@ -27,9 +29,6 @@ import org.apache.dubbo.rpc.model.ProviderMethodModel; import org.apache.dubbo.rpc.model.ProviderModel; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; - import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; @@ -50,19 +49,19 @@ private static Method findMethod(List methods, String metho Class[] paramTypes) { for (ProviderMethodModel model : methods) { Method m = model.getMethod(); - if (isMatch(m, args, paramTypes,method)) { + if (isMatch(m, args, paramTypes, method)) { return m; } } return null; } - private static boolean isMatch(Method method,List args, Class[] paramClasses,String lookupMethodName) { - if(!method.getName().equals(lookupMethodName)) { + private static boolean isMatch(Method method, List args, Class[] paramClasses, String lookupMethodName) { + if (!method.getName().equals(lookupMethodName)) { return false; } - Class types[]=method.getParameterTypes(); + Class types[] = method.getParameterTypes(); if (types.length != args.size()) { return false; } @@ -101,12 +100,19 @@ private static boolean isMatch(Method method,List args, Class[] param } } else if (arg instanceof Map) { String name = (String) ((Map) arg).get("class"); - Class cls = arg.getClass(); - if (name != null && name.length() > 0) { - cls = ReflectUtils.forName(name); - } - if (!type.isAssignableFrom(cls)) { - return false; + if (StringUtils.isNotEmpty(name)) { + Class cls = ReflectUtils.forName(name); + if (!type.isAssignableFrom(cls)) { + return false; + } + } else { + if (arg instanceof JSONObject) { + try { + ((JSONObject) arg).toJavaObject(type); + } catch (Exception ex) { + return false; + } + } } } else if (arg instanceof Collection) { if (!type.isArray() && !type.isAssignableFrom(arg.getClass())) { @@ -133,7 +139,7 @@ public String telnet(Channel channel, String message) { StringBuilder buf = new StringBuilder(); String service = (String) channel.getAttribute(ChangeTelnetHandler.SERVICE_KEY); if (!StringUtils.isEmpty(service)) { - buf.append("Use default service ").append(service).append(".\r\n"); + buf.append("Use default service ").append(service).append("."); } int i = message.indexOf("("); @@ -217,6 +223,7 @@ public String telnet(Channel channel, String message) { result.setException(t); } long end = System.currentTimeMillis(); + buf.append("\r\nresult: "); buf.append(JSON.toJSONString(result.recreate())); buf.append("\r\nelapsed: "); buf.append(end - start); @@ -225,10 +232,10 @@ public String telnet(Channel channel, String message) { return "Failed to invoke method " + invokeMethod.getName() + ", cause: " + StringUtils.toString(t); } } else { - buf.append("No such method ").append(method).append(" in service ").append(service); + buf.append("\r\nNo such method ").append(method).append(" in service ").append(service); } } else { - buf.append("No such service ").append(service); + buf.append("\r\nNo such service ").append(service); } return buf.toString(); } diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/TraceTelnetHandler.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/TraceTelnetHandler.java index 5045b31dacc..a3940e1613e 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/TraceTelnetHandler.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/TraceTelnetHandler.java @@ -45,17 +45,18 @@ public String telnet(Channel channel, String message) { String[] parts = message.split("\\s+"); String method; String times; - if (service == null || service.length() == 0) { + // message like : XxxService , XxxService 10 , XxxService xxxMethod , XxxService xxxMethod 10 + if (StringUtils.isEmpty(service)) { service = parts.length > 0 ? parts[0] : null; method = parts.length > 1 ? parts[1] : null; - } else { + times = parts.length > 2 ? parts[2] : "1"; + } else { //message like : xxxMethod, xxxMethod 10 method = parts.length > 0 ? parts[0] : null; + times = parts.length > 1 ? parts[1] : "1"; } if (StringUtils.isInteger(method)) { times = method; method = null; - } else { - times = parts.length > 2 ? parts[2] : "1"; } if (!StringUtils.isInteger(times)) { return "Illegal times " + times + ", must be integer."; diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java index fe777e37de2..a1323b852b7 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java @@ -47,7 +47,7 @@ public interface DemoService { Type enumlength(Type... types); - Type getType(Type type); + Type getType(Type type); String get(CustomArgument arg1); @@ -63,4 +63,5 @@ public interface DemoService { int getPerson(Person person1, Person perso2); + String getPerson(Man man); } \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java index c1b03f64e25..a5af9be110d 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java @@ -71,7 +71,7 @@ public Type enumlength(Type... types) { return Type.Lower; return types[0]; } - + public Type getType(Type type) { return type; } @@ -109,12 +109,16 @@ public long add(int a, long b) { @Override public int getPerson(Person person) { - return 1; + return person.getAge(); } @Override public int getPerson(Person person1, Person perso2) { - return 2; + return person1.getAge() + perso2.getAge(); } + @Override + public String getPerson(Man man) { + return man.getName(); + } } \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/Man.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/Man.java new file mode 100644 index 00000000000..440630ada1b --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/Man.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.rpc.protocol.dubbo.support; + + +import java.io.Serializable; + +/** + * Man.java + */ +public class Man implements Serializable { + + private static final long serialVersionUID = 1L; + private String name; + private int age; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } +} \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java index 705eb64d06c..fc7ccef811d 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java @@ -25,7 +25,6 @@ import org.apache.dubbo.rpc.protocol.dubbo.support.DemoService; import org.apache.dubbo.rpc.protocol.dubbo.support.DemoServiceImpl; import org.apache.dubbo.rpc.protocol.dubbo.support.ProtocolUtils; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -66,7 +65,7 @@ public void testInvokeDefaultSService() throws RemotingException { ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel); String result = invoke.telnet(mockChannel, "DemoService.echo(\"ok\")"); - assertTrue(result.contains("Use default service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService.\r\n\"ok\"\r\n")); + assertTrue(result.contains("result: \"ok\"")); } @SuppressWarnings("unchecked") @@ -116,7 +115,7 @@ public void testInvokeByPassingEnumValue() throws RemotingException { ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel); String result = invoke.telnet(mockChannel, "getType(\"High\")"); - assertTrue(result.contains("High")); + assertTrue(result.contains("result: \"High\"")); } @@ -133,8 +132,8 @@ public void testComplexParamWithoutSpecifyParamType() throws RemotingException { // pass json value to parameter of Person type - String result = invoke.telnet(mockChannel, "DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12})"); - assertTrue(result.contains("No such method getPerson in service DemoService")); + String result = invoke.telnet(mockChannel, "DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12,\"class\":\"org.apache.dubbo.rpc.protocol.dubbo.support.Person\"})"); + assertTrue(result.contains("result: 12")); } @SuppressWarnings("unchecked") @@ -151,13 +150,13 @@ public void testComplexParamSpecifyParamType() throws RemotingException { // pass json value to parameter of Person type and specify it's type // one parameter with type of Person String result = invoke.telnet(mockChannel, "DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12}) -p org.apache.dubbo.rpc.protocol.dubbo.support.Person"); - assertTrue(result.contains("Use default service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService.\r\n1\r\n")); + assertTrue(result.contains("result: 12")); // two parameter with type of Person result = invoke.telnet(mockChannel, "DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12},{\"name\":\"lisi\",\"age\":12}) " + "-p org.apache.dubbo.rpc.protocol.dubbo.support.Person " + "org.apache.dubbo.rpc.protocol.dubbo.support.Person"); - assertTrue(result.contains("Use default service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService.\r\n2\r\n")); + assertTrue(result.contains("result: 24")); } @SuppressWarnings("unchecked") @@ -195,7 +194,49 @@ public void testInvokeAutoFindMethod() throws RemotingException { ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel); String result = invoke.telnet(mockChannel, "echo(\"ok\")"); - assertTrue(result.contains("ok")); + assertTrue(result.contains("result: \"ok\"")); + } + + @Test + public void testInvokeJsonParamMethod() throws RemotingException { + mockChannel = mock(Channel.class); + given(mockChannel.getAttribute("telnet.service")).willReturn(null); + given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555")); + given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886")); + + ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), DemoService.class); + ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel); + String param = "{\"name\":\"Dubbo\",\"age\":8}"; + String result = invoke.telnet(mockChannel, "getPerson(" + param + ")"); + assertTrue(result.contains("result: 8") || result.contains("result: \"Dubbo\"")); + } + + @Test + public void testInvokeSpecifyTypeJsonParamMethod() throws RemotingException { + mockChannel = mock(Channel.class); + given(mockChannel.getAttribute("telnet.service")).willReturn(null); + given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555")); + given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886")); + + ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), DemoService.class); + ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel); + String param = "{\"name\":\"Dubbo\",\"age\":8,\"class\":\"org.apache.dubbo.rpc.protocol.dubbo.support.Man\"}"; + String result = invoke.telnet(mockChannel, "getPerson(" + param + ")"); + assertTrue(result.contains("result: \"Dubbo\"")); + } + + @Test + public void testInvokeMultiJsonParamMethod() throws RemotingException { + mockChannel = mock(Channel.class); + given(mockChannel.getAttribute("telnet.service")).willReturn(null); + given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555")); + given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886")); + + ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), DemoService.class); + ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel); + String param = "{\"name\":\"Dubbo\",\"age\":8},{\"name\":\"Apache\",\"age\":20}"; + String result = invoke.telnet(mockChannel, "getPerson(" + param + ")"); + assertTrue(result.contains("result: 28")); } @Test