Skip to content

Commit 460c3a1

Browse files
LiZhenNetbeiwei30
authored andcommitted
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
1 parent f4e96a4 commit 460c3a1

File tree

6 files changed

+132
-32
lines changed

6 files changed

+132
-32
lines changed

dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*/
1717
package org.apache.dubbo.rpc.protocol.dubbo.telnet;
1818

19+
import com.alibaba.fastjson.JSON;
20+
import com.alibaba.fastjson.JSONObject;
1921
import org.apache.dubbo.common.extension.Activate;
2022
import org.apache.dubbo.common.utils.ReflectUtils;
2123
import org.apache.dubbo.common.utils.StringUtils;
@@ -27,9 +29,6 @@
2729
import org.apache.dubbo.rpc.model.ProviderMethodModel;
2830
import org.apache.dubbo.rpc.model.ProviderModel;
2931

30-
import com.alibaba.fastjson.JSON;
31-
import com.alibaba.fastjson.JSONObject;
32-
3332
import java.lang.reflect.Method;
3433
import java.util.ArrayList;
3534
import java.util.Collection;
@@ -50,19 +49,19 @@ private static Method findMethod(List<ProviderMethodModel> methods, String metho
5049
Class<?>[] paramTypes) {
5150
for (ProviderMethodModel model : methods) {
5251
Method m = model.getMethod();
53-
if (isMatch(m, args, paramTypes,method)) {
52+
if (isMatch(m, args, paramTypes, method)) {
5453
return m;
5554
}
5655
}
5756
return null;
5857
}
5958

60-
private static boolean isMatch(Method method,List<Object> args, Class<?>[] paramClasses,String lookupMethodName) {
61-
if(!method.getName().equals(lookupMethodName)) {
59+
private static boolean isMatch(Method method, List<Object> args, Class<?>[] paramClasses, String lookupMethodName) {
60+
if (!method.getName().equals(lookupMethodName)) {
6261
return false;
6362
}
6463

65-
Class<?> types[]=method.getParameterTypes();
64+
Class<?> types[] = method.getParameterTypes();
6665
if (types.length != args.size()) {
6766
return false;
6867
}
@@ -101,12 +100,19 @@ private static boolean isMatch(Method method,List<Object> args, Class<?>[] param
101100
}
102101
} else if (arg instanceof Map) {
103102
String name = (String) ((Map<?, ?>) arg).get("class");
104-
Class<?> cls = arg.getClass();
105-
if (name != null && name.length() > 0) {
106-
cls = ReflectUtils.forName(name);
107-
}
108-
if (!type.isAssignableFrom(cls)) {
109-
return false;
103+
if (StringUtils.isNotEmpty(name)) {
104+
Class<?> cls = ReflectUtils.forName(name);
105+
if (!type.isAssignableFrom(cls)) {
106+
return false;
107+
}
108+
} else {
109+
if (arg instanceof JSONObject) {
110+
try {
111+
((JSONObject) arg).toJavaObject(type);
112+
} catch (Exception ex) {
113+
return false;
114+
}
115+
}
110116
}
111117
} else if (arg instanceof Collection) {
112118
if (!type.isArray() && !type.isAssignableFrom(arg.getClass())) {
@@ -133,7 +139,7 @@ public String telnet(Channel channel, String message) {
133139
StringBuilder buf = new StringBuilder();
134140
String service = (String) channel.getAttribute(ChangeTelnetHandler.SERVICE_KEY);
135141
if (!StringUtils.isEmpty(service)) {
136-
buf.append("Use default service ").append(service).append(".\r\n");
142+
buf.append("Use default service ").append(service).append(".");
137143
}
138144

139145
int i = message.indexOf("(");
@@ -217,6 +223,7 @@ public String telnet(Channel channel, String message) {
217223
result.setException(t);
218224
}
219225
long end = System.currentTimeMillis();
226+
buf.append("\r\nresult: ");
220227
buf.append(JSON.toJSONString(result.recreate()));
221228
buf.append("\r\nelapsed: ");
222229
buf.append(end - start);
@@ -225,10 +232,10 @@ public String telnet(Channel channel, String message) {
225232
return "Failed to invoke method " + invokeMethod.getName() + ", cause: " + StringUtils.toString(t);
226233
}
227234
} else {
228-
buf.append("No such method ").append(method).append(" in service ").append(service);
235+
buf.append("\r\nNo such method ").append(method).append(" in service ").append(service);
229236
}
230237
} else {
231-
buf.append("No such service ").append(service);
238+
buf.append("\r\nNo such service ").append(service);
232239
}
233240
return buf.toString();
234241
}

dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/TraceTelnetHandler.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,18 @@ public String telnet(Channel channel, String message) {
4545
String[] parts = message.split("\\s+");
4646
String method;
4747
String times;
48-
if (service == null || service.length() == 0) {
48+
// message like : XxxService , XxxService 10 , XxxService xxxMethod , XxxService xxxMethod 10
49+
if (StringUtils.isEmpty(service)) {
4950
service = parts.length > 0 ? parts[0] : null;
5051
method = parts.length > 1 ? parts[1] : null;
51-
} else {
52+
times = parts.length > 2 ? parts[2] : "1";
53+
} else { //message like : xxxMethod, xxxMethod 10
5254
method = parts.length > 0 ? parts[0] : null;
55+
times = parts.length > 1 ? parts[1] : "1";
5356
}
5457
if (StringUtils.isInteger(method)) {
5558
times = method;
5659
method = null;
57-
} else {
58-
times = parts.length > 2 ? parts[2] : "1";
5960
}
6061
if (!StringUtils.isInteger(times)) {
6162
return "Illegal times " + times + ", must be integer.";

dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public interface DemoService {
4747

4848
Type enumlength(Type... types);
4949

50-
Type getType(Type type);
50+
Type getType(Type type);
5151

5252
String get(CustomArgument arg1);
5353

@@ -63,4 +63,5 @@ public interface DemoService {
6363

6464
int getPerson(Person person1, Person perso2);
6565

66+
String getPerson(Man man);
6667
}

dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/support/DemoServiceImpl.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public Type enumlength(Type... types) {
7171
return Type.Lower;
7272
return types[0];
7373
}
74-
74+
7575
public Type getType(Type type) {
7676
return type;
7777
}
@@ -109,12 +109,16 @@ public long add(int a, long b) {
109109

110110
@Override
111111
public int getPerson(Person person) {
112-
return 1;
112+
return person.getAge();
113113
}
114114

115115
@Override
116116
public int getPerson(Person person1, Person perso2) {
117-
return 2;
117+
return person1.getAge() + perso2.getAge();
118118
}
119119

120+
@Override
121+
public String getPerson(Man man) {
122+
return man.getName();
123+
}
120124
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.dubbo.rpc.protocol.dubbo.support;
18+
19+
20+
import java.io.Serializable;
21+
22+
/**
23+
* Man.java
24+
*/
25+
public class Man implements Serializable {
26+
27+
private static final long serialVersionUID = 1L;
28+
private String name;
29+
private int age;
30+
31+
public String getName() {
32+
return name;
33+
}
34+
35+
public void setName(String name) {
36+
this.name = name;
37+
}
38+
39+
public int getAge() {
40+
return age;
41+
}
42+
43+
public void setAge(int age) {
44+
this.age = age;
45+
}
46+
}

dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokerTelnetHandlerTest.java

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.apache.dubbo.rpc.protocol.dubbo.support.DemoService;
2626
import org.apache.dubbo.rpc.protocol.dubbo.support.DemoServiceImpl;
2727
import org.apache.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
28-
2928
import org.junit.After;
3029
import org.junit.Before;
3130
import org.junit.Test;
@@ -66,7 +65,7 @@ public void testInvokeDefaultSService() throws RemotingException {
6665
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
6766

6867
String result = invoke.telnet(mockChannel, "DemoService.echo(\"ok\")");
69-
assertTrue(result.contains("Use default service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService.\r\n\"ok\"\r\n"));
68+
assertTrue(result.contains("result: \"ok\""));
7069
}
7170

7271
@SuppressWarnings("unchecked")
@@ -116,7 +115,7 @@ public void testInvokeByPassingEnumValue() throws RemotingException {
116115
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
117116

118117
String result = invoke.telnet(mockChannel, "getType(\"High\")");
119-
assertTrue(result.contains("High"));
118+
assertTrue(result.contains("result: \"High\""));
120119
}
121120

122121

@@ -133,8 +132,8 @@ public void testComplexParamWithoutSpecifyParamType() throws RemotingException {
133132

134133
// pass json value to parameter of Person type
135134

136-
String result = invoke.telnet(mockChannel, "DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12})");
137-
assertTrue(result.contains("No such method getPerson in service DemoService"));
135+
String result = invoke.telnet(mockChannel, "DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12,\"class\":\"org.apache.dubbo.rpc.protocol.dubbo.support.Person\"})");
136+
assertTrue(result.contains("result: 12"));
138137
}
139138

140139
@SuppressWarnings("unchecked")
@@ -151,13 +150,13 @@ public void testComplexParamSpecifyParamType() throws RemotingException {
151150
// pass json value to parameter of Person type and specify it's type
152151
// one parameter with type of Person
153152
String result = invoke.telnet(mockChannel, "DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12}) -p org.apache.dubbo.rpc.protocol.dubbo.support.Person");
154-
assertTrue(result.contains("Use default service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService.\r\n1\r\n"));
153+
assertTrue(result.contains("result: 12"));
155154

156155
// two parameter with type of Person
157156
result = invoke.telnet(mockChannel, "DemoService.getPerson({\"name\":\"zhangsan\",\"age\":12},{\"name\":\"lisi\",\"age\":12}) " +
158157
"-p org.apache.dubbo.rpc.protocol.dubbo.support.Person " +
159158
"org.apache.dubbo.rpc.protocol.dubbo.support.Person");
160-
assertTrue(result.contains("Use default service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService.\r\n2\r\n"));
159+
assertTrue(result.contains("result: 24"));
161160
}
162161

163162
@SuppressWarnings("unchecked")
@@ -195,7 +194,49 @@ public void testInvokeAutoFindMethod() throws RemotingException {
195194
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
196195

197196
String result = invoke.telnet(mockChannel, "echo(\"ok\")");
198-
assertTrue(result.contains("ok"));
197+
assertTrue(result.contains("result: \"ok\""));
198+
}
199+
200+
@Test
201+
public void testInvokeJsonParamMethod() throws RemotingException {
202+
mockChannel = mock(Channel.class);
203+
given(mockChannel.getAttribute("telnet.service")).willReturn(null);
204+
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
205+
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
206+
207+
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), DemoService.class);
208+
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
209+
String param = "{\"name\":\"Dubbo\",\"age\":8}";
210+
String result = invoke.telnet(mockChannel, "getPerson(" + param + ")");
211+
assertTrue(result.contains("result: 8") || result.contains("result: \"Dubbo\""));
212+
}
213+
214+
@Test
215+
public void testInvokeSpecifyTypeJsonParamMethod() throws RemotingException {
216+
mockChannel = mock(Channel.class);
217+
given(mockChannel.getAttribute("telnet.service")).willReturn(null);
218+
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
219+
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
220+
221+
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), DemoService.class);
222+
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
223+
String param = "{\"name\":\"Dubbo\",\"age\":8,\"class\":\"org.apache.dubbo.rpc.protocol.dubbo.support.Man\"}";
224+
String result = invoke.telnet(mockChannel, "getPerson(" + param + ")");
225+
assertTrue(result.contains("result: \"Dubbo\""));
226+
}
227+
228+
@Test
229+
public void testInvokeMultiJsonParamMethod() throws RemotingException {
230+
mockChannel = mock(Channel.class);
231+
given(mockChannel.getAttribute("telnet.service")).willReturn(null);
232+
given(mockChannel.getLocalAddress()).willReturn(NetUtils.toAddress("127.0.0.1:5555"));
233+
given(mockChannel.getRemoteAddress()).willReturn(NetUtils.toAddress("127.0.0.1:20886"));
234+
235+
ProviderModel providerModel = new ProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", new DemoServiceImpl(), DemoService.class);
236+
ApplicationModel.initProviderModel("org.apache.dubbo.rpc.protocol.dubbo.support.DemoService", providerModel);
237+
String param = "{\"name\":\"Dubbo\",\"age\":8},{\"name\":\"Apache\",\"age\":20}";
238+
String result = invoke.telnet(mockChannel, "getPerson(" + param + ")");
239+
assertTrue(result.contains("result: 28"));
199240
}
200241

201242
@Test

0 commit comments

Comments
 (0)