in dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java [66:194]
public String execute(CommandContext commandContext, String[] args) {
if (ArrayUtils.isEmpty(args)) {
return "Please input method name, eg: \r\ninvoke xxxMethod(1234, \"abcd\", {\"prop\" : \"value\"})\r\n"
+ "invoke XxxService.xxxMethod(1234, \"abcd\", {\"prop\" : \"value\"})\r\n"
+ "invoke com.xxx.XxxService.xxxMethod(1234, \"abcd\", {\"prop\" : \"value\"})";
}
Channel channel = commandContext.getRemote();
String service = channel.attr(ChangeTelnet.SERVICE_KEY) != null
? channel.attr(ChangeTelnet.SERVICE_KEY).get()
: null;
String message = args[0];
int i = message.indexOf("(");
if (i < 0 || !message.endsWith(")")) {
return "Invalid parameters, format: service.method(args)";
}
String method = message.substring(0, i).trim();
String param = message.substring(i + 1, message.length() - 1).trim();
i = method.lastIndexOf(".");
if (i >= 0) {
service = method.substring(0, i).trim();
method = method.substring(i + 1).trim();
}
if (StringUtils.isEmpty(service)) {
return "If you want to invoke like [invoke sayHello(\"xxxx\")], please execute cd command first,"
+ " or you can execute it like [invoke IHelloService.sayHello(\"xxxx\")]";
}
List<Object> list;
try {
list = JsonUtils.toJavaList("[" + param + "]", Object.class);
} catch (Throwable t) {
return "Invalid json argument, cause: " + t.getMessage();
}
StringBuilder buf = new StringBuilder();
Method invokeMethod = null;
ProviderModel selectedProvider = null;
if (isInvokedSelectCommand(channel)) {
selectedProvider = channel.attr(INVOKE_METHOD_PROVIDER_KEY).get();
invokeMethod = channel.attr(SelectTelnet.SELECT_METHOD_KEY).get();
} else {
for (ProviderModel provider : frameworkModel.getServiceRepository().allProviderModels()) {
if (!isServiceMatch(service, provider)) {
continue;
}
selectedProvider = provider;
List<Method> methodList = findSameSignatureMethod(provider.getAllMethods(), method, list);
if (CollectionUtils.isEmpty(methodList)) {
break;
}
if (methodList.size() == 1) {
invokeMethod = methodList.get(0);
} else {
List<Method> matchMethods = findMatchMethods(methodList, list);
if (CollectionUtils.isEmpty(matchMethods)) {
break;
}
if (matchMethods.size() == 1) {
invokeMethod = matchMethods.get(0);
} else { // exist overridden method
channel.attr(INVOKE_METHOD_PROVIDER_KEY).set(provider);
channel.attr(INVOKE_METHOD_LIST_KEY).set(matchMethods);
channel.attr(INVOKE_MESSAGE_KEY).set(message);
printSelectMessage(buf, matchMethods);
return buf.toString();
}
}
break;
}
}
if (!StringUtils.isEmpty(service)) {
buf.append("Use default service ").append(service).append('.');
}
if (selectedProvider == null) {
buf.append("\r\nNo such service ").append(service);
return buf.toString();
}
if (invokeMethod == null) {
buf.append("\r\nNo such method ")
.append(method)
.append(" in service ")
.append(service);
return buf.toString();
}
try {
Object[] array =
realize(list.toArray(), invokeMethod.getParameterTypes(), invokeMethod.getGenericParameterTypes());
long start = System.currentTimeMillis();
AppResponse result = new AppResponse();
try {
Object o = invokeMethod.invoke(selectedProvider.getServiceInstance(), array);
boolean setValueDone = false;
if (RpcContext.getServerAttachment().isAsyncStarted()) {
AsyncContext asyncContext = RpcContext.getServerAttachment().getAsyncContext();
if (asyncContext instanceof AsyncContextImpl) {
CompletableFuture<Object> internalFuture =
((AsyncContextImpl) asyncContext).getInternalFuture();
result.setValue(internalFuture.get());
setValueDone = true;
}
}
if (!setValueDone) {
result.setValue(o);
}
} catch (Throwable t) {
result.setException(t);
if (t instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
} finally {
RpcContext.removeContext();
}
long end = System.currentTimeMillis();
buf.append("\r\nresult: ");
buf.append(JsonUtils.toJson(result.recreate()));
buf.append("\r\nelapsed: ");
buf.append(end - start);
buf.append(" ms.");
} catch (Throwable t) {
return "Failed to invoke method " + invokeMethod.getName() + ", cause: " + StringUtils.toString(t);
}
return buf.toString();
}