fix telnet trace times is always 1 (#3038)
* fix telnet trace times is always 1 * use StringUtils determine if the string is empty * Fix 3105 , make invoke command with Json string parameter without "class" key * Fix 3105 ,Keep the class key to support overloaded methods * optimize InvokerTelnetHandlerTest
This commit is contained in:
parent
f4e96a4bb2
commit
460c3a1756
|
|
@ -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.ApplicationModel;
|
|||
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 @@ public class InvokeTelnetHandler implements TelnetHandler {
|
|||
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<Object> args, Class<?>[] paramClasses,String lookupMethodName) {
|
||||
if(!method.getName().equals(lookupMethodName)) {
|
||||
private static boolean isMatch(Method method, List<Object> 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 @@ public class InvokeTelnetHandler implements TelnetHandler {
|
|||
}
|
||||
} 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 class InvokeTelnetHandler implements TelnetHandler {
|
|||
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 class InvokeTelnetHandler implements TelnetHandler {
|
|||
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 class InvokeTelnetHandler implements TelnetHandler {
|
|||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,17 +45,18 @@ public class TraceTelnetHandler implements TelnetHandler {
|
|||
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.";
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ public class DemoServiceImpl implements DemoService {
|
|||
return Type.Lower;
|
||||
return types[0];
|
||||
}
|
||||
|
||||
|
||||
public Type getType(Type type) {
|
||||
return type;
|
||||
}
|
||||
|
|
@ -109,12 +109,16 @@ public class DemoServiceImpl implements DemoService {
|
|||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,6 @@ import org.apache.dubbo.rpc.model.ProviderModel;
|
|||
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 class InvokerTelnetHandlerTest {
|
|||
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 class InvokerTelnetHandlerTest {
|
|||
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 class InvokerTelnetHandlerTest {
|
|||
|
||||
// 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 class InvokerTelnetHandlerTest {
|
|||
// 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 class InvokerTelnetHandlerTest {
|
|||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue