diff --git a/src/main/java/io/github/ningyu/jmeter/plugin/dubbo/gui/DubboCommonPanel.java b/src/main/java/io/github/ningyu/jmeter/plugin/dubbo/gui/DubboCommonPanel.java index 4a28be5..380b403 100644 --- a/src/main/java/io/github/ningyu/jmeter/plugin/dubbo/gui/DubboCommonPanel.java +++ b/src/main/java/io/github/ningyu/jmeter/plugin/dubbo/gui/DubboCommonPanel.java @@ -57,9 +57,13 @@ public class DubboCommonPanel { private JTextField connectionsText; private JComboBox loadbalanceText; private JComboBox asyncText; + //参数表格 private DefaultTableModel model; private String[] columnNames = {"paramType", "paramValue"}; private String[] tmpRow = {"", ""}; + //隐式参数表格 + private DefaultTableModel modelAttachment; + private String[] columnNamesAttachment = {"key", "value"}; private int textColumns = 2; private JAutoCompleteComboBox interfaceList; private JAutoCompleteComboBox methodList; @@ -262,12 +266,11 @@ public void propertyChange(PropertyChangeEvent evt) { mh.add(makeHelper("The service method name")); interfaceSettings.add(mh); - //表格panel + //选项卡 + JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP); + //接口参数表格 JPanel tablePanel = new HorizontalPanel(); - //Args - JLabel argsLable = new JLabel(" Args:", SwingConstants.RIGHT); model = new DefaultTableModel(); -// model.setDataVector(new String[][]{{"", ""}}, columnNames); model.setDataVector(null, columnNames); final JTable table = new JTable(model); table.setRowHeight(40); @@ -293,11 +296,45 @@ public void actionPerformed(ActionEvent arg0) { }); //表格滚动条 JScrollPane scrollpane = new JScrollPane(table); - tablePanel.add(argsLable); tablePanel.add(scrollpane); tablePanel.add(addBtn); tablePanel.add(delBtn); - interfaceSettings.add(tablePanel); + tabbedPane.add("Args",tablePanel); + + //隐式参数表格 + JPanel tablePanelAttachment = new HorizontalPanel(); + modelAttachment = new DefaultTableModel(); + modelAttachment.setDataVector(null, columnNamesAttachment); + final JTable tableAttachment = new JTable(modelAttachment); + tableAttachment.setRowHeight(40); + //失去光标退出编辑 + tableAttachment.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); + //添加按钮 + JButton addBtnAttachment = new JButton("增加"); + addBtnAttachment.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + modelAttachment.addRow(tmpRow); + } + }); + JButton delBtnAttachment = new JButton("删除"); + delBtnAttachment.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + int rowIndex = tableAttachment.getSelectedRow(); + if(rowIndex != -1) { + modelAttachment.removeRow(rowIndex); + } + } + }); + //表格滚动条 + JScrollPane scrollpaneAttachment = new JScrollPane(tableAttachment); + tablePanelAttachment.add(scrollpaneAttachment); + tablePanelAttachment.add(addBtnAttachment); + tablePanelAttachment.add(delBtnAttachment); + tabbedPane.add("Attachment Args",tablePanelAttachment); + + interfaceSettings.add(tabbedPane); return interfaceSettings; } @@ -329,6 +366,10 @@ public void configureInterface(TestElement element) { columnNames.add("paramType"); columnNames.add("paramValue"); model.setDataVector(paserMethodArgsData(Constants.getMethodArgs(element)), columnNames); + Vector columnNamesAttachment = new Vector(); + columnNamesAttachment.add("key"); + columnNamesAttachment.add("value"); + modelAttachment.setDataVector(paserMethodArgsData(Constants.getAttachmentArgs(element)), columnNamesAttachment); } public void modifyRegistry(TestElement element) { @@ -353,6 +394,7 @@ public void modifyInterface(TestElement element) { Constants.setInterfaceName(interfaceText.getText(), element); Constants.setMethod(methodText.getText(), element); Constants.setMethodArgs(getMethodArgsData(model.getDataVector()), element); + Constants.setAttachmentArgs(getMethodArgsData(modelAttachment.getDataVector()), element); } public void clearRegistry() { registryProtocolText.setSelectedIndex(0); @@ -376,6 +418,7 @@ public void clearInterface() { interfaceText.setText(""); methodText.setText(""); model.setDataVector(null, columnNames); + modelAttachment.setDataVector(null, columnNamesAttachment); } private List getMethodArgsData(Vector> data) { diff --git a/src/main/java/io/github/ningyu/jmeter/plugin/dubbo/sample/DubboSample.java b/src/main/java/io/github/ningyu/jmeter/plugin/dubbo/sample/DubboSample.java index 81dbb1b..c322089 100644 --- a/src/main/java/io/github/ningyu/jmeter/plugin/dubbo/sample/DubboSample.java +++ b/src/main/java/io/github/ningyu/jmeter/plugin/dubbo/sample/DubboSample.java @@ -25,6 +25,7 @@ import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.utils.ReferenceConfigCache; +import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.service.GenericService; import org.apache.jmeter.samplers.AbstractSampler; import org.apache.jmeter.samplers.Entry; @@ -37,6 +38,8 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * DubboSample @@ -88,6 +91,7 @@ private String getSampleData() { sb.append("Interface: ").append(Constants.getInterface(this)).append("\n"); sb.append("Method: ").append(Constants.getMethod(this)).append("\n"); sb.append("Method Args: ").append(Constants.getMethodArgs(this).toString()); + sb.append("Attachment Args: ").append(Constants.getAttachmentArgs(this).toString()); return sb.toString(); } @@ -145,7 +149,14 @@ private Object callDubbo(SampleResult res) { default: // direct invoke provider StringBuffer sb = new StringBuffer(); - sb.append(Constants.getRpcProtocol(this)).append(Constants.getAddress(this)).append("/").append(Constants.getInterface(this)); + sb.append(Constants.getRpcProtocol(this)) + .append(Constants.getAddress(this)) + .append("/").append(Constants.getInterface(this)); + //# fix dubbo 2.7.3 Generic bug https://github.com/apache/dubbo/pull/4787 + String version = Constants.getVersion(this); + if (!StringUtils.isBlank(version)) { + sb.append(":").append(version); + } log.debug("rpc invoker url : " + sb.toString()); reference.setUrl(sb.toString()); } @@ -262,6 +273,11 @@ public String generateKey(org.apache.dubbo.config.ReferenceConfig referenceCo parameterTypes = paramterTypeList.toArray(new String[paramterTypeList.size()]); parameterValues = parameterValuesList.toArray(new Object[parameterValuesList.size()]); + List attachmentArgs = Constants.getAttachmentArgs(this); + if (attachmentArgs != null && !attachmentArgs.isEmpty()) { + RpcContext.getContext().setAttachments(attachmentArgs.stream().collect(Collectors.toMap(MethodArgument::getParamType, MethodArgument::getParamValue))); + } + res.sampleStart(); Object result = null; try { diff --git a/src/main/java/io/github/ningyu/jmeter/plugin/util/Constants.java b/src/main/java/io/github/ningyu/jmeter/plugin/util/Constants.java index f44d93b..c6460a2 100644 --- a/src/main/java/io/github/ningyu/jmeter/plugin/util/Constants.java +++ b/src/main/java/io/github/ningyu/jmeter/plugin/util/Constants.java @@ -82,6 +82,8 @@ public class Constants { public static final String FIELD_DUBBO_METHOD = "FIELD_DUBBO_METHOD"; public static final String FIELD_DUBBO_METHOD_ARGS = "FIELD_DUBBO_METHOD_ARGS"; public static final String FIELD_DUBBO_METHOD_ARGS_SIZE = "FIELD_DUBBO_METHOD_ARGS_SIZE"; + public static final String FIELD_DUBBO_ATTACHMENT_ARGS = "FIELD_DUBBO_ATTACHMENT_ARGS"; + public static final String FIELD_DUBBO_ATTACHMENT_ARGS_SIZE = "FIELD_DUBBO_ATTACHMENT_ARGS_SIZE"; public static final String DEFAULT_TIMEOUT = "1000"; public static final String DEFAULT_VERSION = "1.0"; public static final String DEFAULT_RETRIES = "0"; @@ -354,4 +356,35 @@ public static final void setMethodArgs(List methodArgs, TestElem } } + /** + * get attachmentArgs + * @return the attachmentArgs + */ + public static final List getAttachmentArgs(TestElement element) { + int paramsSize = element.getPropertyAsInt(FIELD_DUBBO_ATTACHMENT_ARGS_SIZE, 0); + List list = new ArrayList(); + for (int i = 1; i <= paramsSize; i++) { + String paramType = element.getPropertyAsString(FIELD_DUBBO_ATTACHMENT_ARGS + "_KEY" + i); + String paramValue = element.getPropertyAsString(FIELD_DUBBO_ATTACHMENT_ARGS + "_VALUE" + i); + MethodArgument args = new MethodArgument(paramType, paramValue); + list.add(args); + } + return list; + } + + /** + * set attachmentArgs + * @param methodArgs the attachmentArgs to set + */ + public static final void setAttachmentArgs(List methodArgs, TestElement element) { + int size = methodArgs == null ? 0 : methodArgs.size(); + element.setProperty(new IntegerProperty(FIELD_DUBBO_ATTACHMENT_ARGS_SIZE, size)); + if (size > 0) { + for (int i = 1; i <= methodArgs.size(); i++) { + element.setProperty(new StringProperty(FIELD_DUBBO_ATTACHMENT_ARGS + "_KEY" + i, methodArgs.get(i-1).getParamType())); + element.setProperty(new StringProperty(FIELD_DUBBO_ATTACHMENT_ARGS + "_VALUE" + i, methodArgs.get(i-1).getParamValue())); + } + } + } + } diff --git a/src/test/java/io/github/ningyu/jmeter/plugin/GenericServiceTest.java b/src/test/java/io/github/ningyu/jmeter/plugin/GenericServiceTest.java new file mode 100644 index 0000000..2fa25ea --- /dev/null +++ b/src/test/java/io/github/ningyu/jmeter/plugin/GenericServiceTest.java @@ -0,0 +1,30 @@ +package io.github.ningyu.jmeter.plugin; + +import io.github.ningyu.jmeter.plugin.util.JsonUtils; +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.ReferenceConfig; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.service.GenericService; +import org.junit.Test; + +public class GenericServiceTest { + @Test + public void test() { + ApplicationConfig application = new ApplicationConfig(); + application.setName("api-generic-consumer"); + ReferenceConfig reference = new ReferenceConfig<>(); + reference.setUrl("dubbo://192.168.56.1:20880/org.apache.dubbo.samples.basic.api.DemoService"); +// reference.setVersion("1.0.0"); + reference.setTimeout(2000); +// reference.setGroup("test"); + reference.setGeneric(true); + reference.setApplication(application); + reference.setInterface("com.jiuyescm.account.api.IUserService"); + GenericService genericService = reference.get(); + RpcContext.getContext().setAttachment("test.ningyu","this is attachmentValue"); +// Object obj = genericService.$invoke("getUserById", new String[]{Long.class.getName()}, new Long[]{1L}); + Object obj = genericService.$invoke("sayHello", new String[]{String.class.getName()}, new String[]{"ningyu"}); + String json = JsonUtils.toJson(obj); + System.out.println(json); + } +}