This is an automated email from the ASF dual-hosted git repository.

iluo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new d32ff60  [Dubbo-2766]Fix 2766 and enhance the invoke command (#2801)
d32ff60 is described below

commit d32ff6065ea7e90c023ad514545a33d525b50e71
Author: kexianjun <kexianjun1...@hotmail.com>
AuthorDate: Tue Dec 11 15:59:02 2018 +0800

    [Dubbo-2766]Fix 2766 and enhance the invoke command (#2801)
    
    * add getter and setter for ServiceConfig's interfaceName property#2353
    
    * add interfaceName to ignoreAttributeNames and change the unit test
    
    * delete the demo source code and update the unit test
    
    * unchange ServiceConfig
    
    * update unit test
    
    * update unit test
    
    * fix https://github.com/apache/incubator-dubbo/issues/2798 and enhance 
invoke command
---
 .../telnet/support/command/HelpTelnetHandler.java  |  4 +-
 .../protocol/dubbo/telnet/InvokeTelnetHandler.java | 58 ++++++++++++++---
 .../rpc/protocol/dubbo/support/DemoService.java    |  4 ++
 .../protocol/dubbo/support/DemoServiceImpl.java    | 10 +++
 .../dubbo/telnet/InvokerTelnetHandlerTest.java     | 72 ++++++++++++++++++++++
 5 files changed, 137 insertions(+), 11 deletions(-)

diff --git 
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/telnet/support/command/HelpTelnetHandler.java
 
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/telnet/support/command/HelpTelnetHandler.java
index 26335f0..8432591 100644
--- 
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/telnet/support/command/HelpTelnetHandler.java
+++ 
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/telnet/support/command/HelpTelnetHandler.java
@@ -59,9 +59,9 @@ public class HelpTelnetHandler implements TelnetHandler {
                     Help help = handler.getClass().getAnnotation(Help.class);
                     List<String> row = new ArrayList<String>();
                     String parameter = " " + 
extensionLoader.getExtensionName(handler) + " " + (help != null ? 
help.parameter().replace("\r\n", " ").replace("\n", " ") : "");
-                    row.add(parameter.length() > 50 ? parameter.substring(0, 
50) + "..." : parameter);
+                    row.add(parameter.length() > 55 ? parameter.substring(0, 
55) + "..." : parameter);
                     String summary = help != null ? 
help.summary().replace("\r\n", " ").replace("\n", " ") : "";
-                    row.add(summary.length() > 50 ? summary.substring(0, 50) + 
"..." : summary);
+                    row.add(summary.length() > 55 ? summary.substring(0, 55) + 
"..." : summary);
                     table.add(row);
                 }
             }
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 caa9f9a..a472fb7 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
@@ -30,8 +30,10 @@ import org.apache.dubbo.rpc.RpcInvocation;
 import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -40,21 +42,21 @@ import java.util.Map;
  * InvokeTelnetHandler
  */
 @Activate
-@Help(parameter = "[service.]method(args)", summary = "Invoke the service 
method.", detail = "Invoke the service method.")
+@Help(parameter = "[service.]method(args) [-p parameter classes]", summary = 
"Invoke the service method.", detail = "Invoke the service method.")
 public class InvokeTelnetHandler implements TelnetHandler {
 
-    private static Method findMethod(Exporter<?> exporter, String method, 
List<Object> args) {
+    private static Method findMethod(Exporter<?> exporter, String method, 
List<Object> args, Class<?>[] paramClases) {
         Invoker<?> invoker = exporter.getInvoker();
         Method[] methods = invoker.getInterface().getMethods();
         for (Method m : methods) {
-            if (m.getName().equals(method) && isMatch(m.getParameterTypes(), 
args)) {
+            if (m.getName().equals(method) && isMatch(m.getParameterTypes(), 
args, paramClases)) {
                 return m;
             }
         }
         return null;
     }
 
-    private static boolean isMatch(Class<?>[] types, List<Object> args) {
+    private static boolean isMatch(Class<?>[] types, List<Object> args, 
Class<?>[] paramClasses) {
         if (types.length != args.size()) {
             return false;
         }
@@ -62,6 +64,10 @@ public class InvokeTelnetHandler implements TelnetHandler {
             Class<?> type = types[i];
             Object arg = args.get(i);
 
+            if (paramClasses != null && type != paramClasses[i]) {
+                return false;
+            }
+
             if (arg == null) {
                 // if the type is primitive, the method to invoke will cause 
NullPointerException definitely
                 // so we can offer a specified error message to the invoker in 
advance and avoid unnecessary invoking
@@ -83,8 +89,8 @@ public class InvokeTelnetHandler implements TelnetHandler {
                 if (!ReflectUtils.isPrimitive(type)) {
                     return false;
                 }
-                Class<?> boxedType = ReflectUtils.getBoxedClass(type);
-                if (boxedType != arg.getClass()) {
+
+                if (!ReflectUtils.isCompatible(type, arg)) {
                     return false;
                 }
             } else if (arg instanceof Map) {
@@ -121,6 +127,26 @@ public class InvokeTelnetHandler implements TelnetHandler {
             buf.append("Use default service " + service + ".\r\n");
         }
         int i = message.indexOf("(");
+        String originalMessage = message;
+        Class<?>[] paramClasses = null;
+        if (message.contains("-p")) {
+            message = originalMessage.substring(0, 
originalMessage.indexOf("-p")).trim();
+            String paramClassesString = 
originalMessage.substring(originalMessage.indexOf("-p") + 2).trim();
+            if (paramClassesString.length() > 0) {
+                String[] split = paramClassesString.split("\\s+");
+                if (split.length > 0) {
+                    paramClasses = new Class[split.length];
+                    for (int j = 0; j < split.length; j++) {
+                        try {
+                            paramClasses[j] = Class.forName(split[j]);
+                        } catch (ClassNotFoundException e) {
+                            return "Unknown parameter class for name " + 
split[j];
+                        }
+                    }
+
+                }
+            }
+        }
         if (i < 0 || !message.endsWith(")")) {
             return "Invalid parameters, format: service.method(args)";
         }
@@ -137,11 +163,26 @@ public class InvokeTelnetHandler implements TelnetHandler 
{
         } catch (Throwable t) {
             return "Invalid json argument, cause: " + t.getMessage();
         }
+        if (paramClasses != null) {
+            if (paramClasses.length != list.size()) {
+                return "Parameter's number does not match the number of 
parameter class";
+            }
+            List<Object> listOfActualClass = new ArrayList<>(list.size());
+            for (int ii = 0; ii < list.size(); ii++) {
+                if (list.get(ii) instanceof JSONObject) {
+                    JSONObject jsonObject = (JSONObject) list.get(ii);
+                    
listOfActualClass.add(jsonObject.toJavaObject(paramClasses[ii]));
+                } else {
+                    listOfActualClass.add(list.get(ii));
+                }
+            }
+            list = listOfActualClass;
+        }
         Invoker<?> invoker = null;
         Method invokeMethod = null;
         for (Exporter<?> exporter : 
DubboProtocol.getDubboProtocol().getExporters()) {
             if (service == null || service.length() == 0) {
-                invokeMethod = findMethod(exporter, method, list);
+                invokeMethod = findMethod(exporter, method, list, 
paramClasses);
                 if (invokeMethod != null) {
                     invoker = exporter.getInvoker();
                     break;
@@ -150,7 +191,7 @@ public class InvokeTelnetHandler implements TelnetHandler {
                 if 
(service.equals(exporter.getInvoker().getInterface().getSimpleName())
                         || 
service.equals(exporter.getInvoker().getInterface().getName())
                         || 
service.equals(exporter.getInvoker().getUrl().getPath())) {
-                    invokeMethod = findMethod(exporter, method, list);
+                    invokeMethod = findMethod(exporter, method, list, 
paramClasses);
                     invoker = exporter.getInvoker();
                     break;
                 }
@@ -179,5 +220,4 @@ public class InvokeTelnetHandler implements TelnetHandler {
         }
         return buf.toString();
     }
-
 }
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 db85cc5..fe777e3 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
@@ -59,4 +59,8 @@ public interface DemoService {
 
     long add(int a, long b);
 
+    int getPerson(Person person);
+
+    int getPerson(Person person1, Person perso2);
+
 }
\ 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 ed38344..c1b03f6 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
@@ -107,4 +107,14 @@ public class DemoServiceImpl implements DemoService {
         return a + b;
     }
 
+    @Override
+    public int getPerson(Person person) {
+        return 1;
+    }
+
+    @Override
+    public int getPerson(Person person1, Person perso2) {
+        return 2;
+    }
+
 }
\ 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 dc63c8b..a28bc99 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
@@ -127,6 +127,78 @@ public class InvokerTelnetHandlerTest {
 
     @SuppressWarnings("unchecked")
     @Test
+    public void testComplexParamWithoutSpecifyParamType() throws 
RemotingException {
+        mockInvoker = mock(Invoker.class);
+        given(mockInvoker.getInterface()).willReturn(DemoService.class);
+        
given(mockInvoker.getUrl()).willReturn(URL.valueOf("dubbo://127.0.0.1:20886/demo"));
+        given(mockInvoker.invoke(any(Invocation.class))).willReturn(new 
RpcResult("ok"));
+        mockChannel = mock(Channel.class);
+        
given(mockChannel.getAttribute("telnet.service")).willReturn("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService");
+        
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
+        
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
+
+        DubboProtocol.getDubboProtocol().export(mockInvoker);
+
+        // 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"));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testComplexParamSpecifyParamType() throws RemotingException {
+        mockInvoker = mock(Invoker.class);
+        given(mockInvoker.getInterface()).willReturn(DemoService.class);
+        
given(mockInvoker.getUrl()).willReturn(URL.valueOf("dubbo://127.0.0.1:20886/demo"));
+        given(mockInvoker.invoke(any(Invocation.class))).willReturn(new 
RpcResult("ok"));
+        mockChannel = mock(Channel.class);
+        
given(mockChannel.getAttribute("telnet.service")).willReturn("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService");
+        
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
+        
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
+
+        DubboProtocol.getDubboProtocol().export(mockInvoker);
+
+        // 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\n\"ok\"\r\n"));
+
+        // 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\n\"ok\"\r\n"));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testComplexParamSpecifyWrongParamType() throws 
RemotingException {
+        mockInvoker = mock(Invoker.class);
+        given(mockInvoker.getInterface()).willReturn(DemoService.class);
+        
given(mockInvoker.getUrl()).willReturn(URL.valueOf("dubbo://127.0.0.1:20886/demo"));
+        given(mockInvoker.invoke(any(Invocation.class))).willReturn(new 
RpcResult("ok"));
+        mockChannel = mock(Channel.class);
+        
given(mockChannel.getAttribute("telnet.service")).willReturn("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService");
+        
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
+        
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
+
+        DubboProtocol.getDubboProtocol().export(mockInvoker);
+
+        // pass json value to parameter of Person type
+        // wrong name of parameter class
+        String result = invoke.telnet(mockChannel, 
"DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12}) -p wrongType");
+        assertEquals("Unknown parameter class for name wrongType", result);
+
+        // wrong number of parameter class
+        result = invoke.telnet(mockChannel, 
"DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12},{\"name\":\"lisi\",\"age\":12})
 " +
+                "-p org.apache.dubbo.rpc.protocol.dubbo.support.Person");
+        assertEquals("Parameter's number does not match the number of 
parameter class", result);
+    }
+
+
+    @SuppressWarnings("unchecked")
+    @Test
     public void testInvokeAutoFindMethod() throws RemotingException {
         mockInvoker = mock(Invoker.class);
         given(mockInvoker.getInterface()).willReturn(DemoService.class);

Reply via email to