diff --git a/backend/pom.xml b/backend/pom.xml
index 742a2efd97..8acf99d312 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -154,6 +154,26 @@
+
+ org.apache.dubbo
+ dubbo
+ 2.7.7
+
+
+ org.apache.zookeeper
+ zookeeper
+ 3.4.13
+
+
+ org.apache.curator
+ curator-framework
+ 4.0.1
+
+
+ org.apache.curator
+ curator-recipes
+ 4.0.1
+
com.alibaba
diff --git a/backend/src/main/java/io/metersphere/api/dubbo/MethodArgument.java b/backend/src/main/java/io/metersphere/api/dubbo/MethodArgument.java
new file mode 100644
index 0000000000..a9efb359b8
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dubbo/MethodArgument.java
@@ -0,0 +1,92 @@
+/*
+ * 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 io.metersphere.api.dubbo;
+
+
+import io.metersphere.api.dubbo.utils.JsonUtils;
+import io.metersphere.api.dubbo.utils.StringUtils;
+
+import java.io.Serializable;
+
+
+/**
+ * MethodArgument
+ */
+public class MethodArgument implements Serializable {
+
+ private static final long serialVersionUID = -2567457932227227262L;
+ private String paramType;
+ private String paramValue;
+
+ public MethodArgument(String paramType, String paramValue) {
+ setParamType(paramType);
+ setParamValue(paramValue);
+ }
+
+ public String getParamType() {
+ return paramType;
+ }
+
+ public void setParamType(String paramType) {
+ this.paramType = (paramType == null ? null : StringUtils.trimAllWhitespace(paramType));
+ }
+
+ public String getParamValue() {
+ return paramValue;
+ }
+
+ public void setParamValue(String paramValue) {
+ this.paramValue = (paramValue == null ? null : StringUtils.trimWhitespace(paramValue));
+ }
+
+ @Override
+ public String toString() {
+ return JsonUtils.toJson(this);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((paramType == null) ? 0 : paramType.hashCode());
+ result = prime * result + ((paramValue == null) ? 0 : paramValue.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MethodArgument other = (MethodArgument) obj;
+ if (paramType == null) {
+ if (other.paramType != null)
+ return false;
+ } else if (!paramType.equals(other.paramType))
+ return false;
+ if (paramValue == null) {
+ if (other.paramValue != null)
+ return false;
+ } else if (!paramValue.equals(other.paramValue))
+ return false;
+ return true;
+ }
+
+}
diff --git a/backend/src/main/java/io/metersphere/api/dubbo/ProviderService.java b/backend/src/main/java/io/metersphere/api/dubbo/ProviderService.java
new file mode 100644
index 0000000000..3478a864ac
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dubbo/ProviderService.java
@@ -0,0 +1,112 @@
+package io.metersphere.api.dubbo;
+
+import io.metersphere.api.dubbo.utils.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.ReferenceConfigBase;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.utils.ReferenceConfigCache;
+import org.apache.dubbo.registry.RegistryService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * ProviderService
+ */
+public class ProviderService implements Serializable {
+
+ private static final Logger log = LoggerFactory.getLogger(ProviderService.class);
+
+ private static final long serialVersionUID = -750353929981409079L;
+ ConcurrentMap> providerUrls = null;
+
+ private static ConcurrentMap cache = new ConcurrentHashMap<>();
+
+ public static ProviderService get(String key) {
+ ProviderService service = cache.get(key);
+ if (service == null) {
+ cache.putIfAbsent(key, new ProviderService());
+ service = cache.get(key);
+ }
+ return service;
+ }
+
+ public Map findByService(String serviceName) {
+ return providerUrls == null ? null : providerUrls.get(serviceName);
+ }
+
+ public List getProviders(String protocol, String address, String group) throws RuntimeException {
+ if (protocol.equals("zookeeper") || protocol.equals("nacos") || protocol.equals("redis")) {
+ return executeRegistry(protocol, address, group);
+// } else if (protocol.equals("none")) {
+// return executeTelnet();
+ } else {
+ throw new RuntimeException("Registry Protocol please use zookeeper or nacos or redis!");
+ }
+ }
+
+ private List executeTelnet() throws RuntimeException {
+ throw new RuntimeException();
+ }
+
+ private List executeRegistry(String protocol, String address, String group) throws RuntimeException {
+ ReferenceConfig reference = new ReferenceConfig();
+ // set application
+ reference.setApplication(new ApplicationConfig("DubboSample"));
+ RegistryConfig registry = null;
+ switch (protocol) {
+ case Constants.REGISTRY_ZOOKEEPER:
+ registry = new RegistryConfig();
+ registry.setProtocol(Constants.REGISTRY_ZOOKEEPER);
+ registry.setGroup(group);
+ registry.setAddress(address);
+ reference.setRegistry(registry);
+ break;
+ case Constants.REGISTRY_NACOS:
+ registry = new RegistryConfig();
+ registry.setProtocol(Constants.REGISTRY_NACOS);
+ registry.setGroup(group);
+ registry.setAddress(address);
+ reference.setRegistry(registry);
+ break;
+ case Constants.REGISTRY_REDIS:
+ registry = new RegistryConfig();
+ registry.setProtocol(Constants.REGISTRY_REDIS);
+ registry.setGroup(group);
+ registry.setAddress(address);
+ reference.setRegistry(registry);
+ break;
+ }
+ reference.setInterface("org.apache.dubbo.registry.RegistryService");
+ try {
+ ReferenceConfigCache cache = ReferenceConfigCache.getCache(address + "_" + group, new ReferenceConfigCache.KeyGenerator() {
+
+ @Override
+ public String generateKey(ReferenceConfigBase> referenceConfig) {
+ return referenceConfig.toString();
+ }
+ });
+ RegistryService registryService = (RegistryService) cache.get(reference);
+ if (registryService == null) {
+ throw new RuntimeException("Can't get the interface list, please check if the address is wrong!");
+ }
+ RegistryServerSync registryServerSync = RegistryServerSync.get(address + "_" + group);
+ registryService.subscribe(RegistryServerSync.SUBSCRIBE, registryServerSync);
+ List ret = new ArrayList();
+ providerUrls = registryServerSync.getRegistryCache().get(com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY);
+ if (providerUrls != null) ret.addAll(providerUrls.keySet());
+ return ret;
+ } catch (Exception e) {
+ log.error("get provider list is error!", e);
+ throw new RuntimeException("Can't get the interface list, please check if the address is wrong!", e);
+ }
+ }
+}
diff --git a/backend/src/main/java/io/metersphere/api/dubbo/RegistryServerSync.java b/backend/src/main/java/io/metersphere/api/dubbo/RegistryServerSync.java
new file mode 100644
index 0000000000..6a58c8349d
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dubbo/RegistryServerSync.java
@@ -0,0 +1,171 @@
+package io.metersphere.api.dubbo;
+
+import io.metersphere.api.dubbo.utils.MD5Util;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.constants.RegistryConstants;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.registry.Constants;
+import org.apache.dubbo.registry.NotifyListener;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * RegistryServerSync
+ */
+public class RegistryServerSync implements NotifyListener, Serializable {
+
+ private static final long serialVersionUID = -1744756264793278229L;
+ private static ConcurrentMap cache = new ConcurrentHashMap<>();
+
+ public static RegistryServerSync get(String key) {
+ RegistryServerSync sync = cache.get(key);
+ if (sync == null) {
+ cache.putIfAbsent(key, new RegistryServerSync());
+ sync = cache.get(key);
+ }
+ return sync;
+ }
+
+ public static final URL SUBSCRIBE = new URL(Constants.ADMIN_PROTOCOL, NetUtils.getLocalHost(), 0, "",
+ CommonConstants.INTERFACE_KEY, CommonConstants.ANY_VALUE,
+ CommonConstants.GROUP_KEY, CommonConstants.ANY_VALUE,
+ CommonConstants.VERSION_KEY, CommonConstants.ANY_VALUE,
+ CommonConstants.CLASSIFIER_KEY, CommonConstants.ANY_VALUE,
+ RegistryConstants.CATEGORY_KEY, RegistryConstants.PROVIDERS_CATEGORY,
+// Constants.CATEGORY_KEY, Constants.PROVIDERS_CATEGORY + ","
+// + Constants.CONSUMERS_CATEGORY + ","
+// + Constants.ROUTERS_CATEGORY + ","
+// + Constants.CONFIGURATORS_CATEGORY,
+ CommonConstants.ENABLED_KEY, CommonConstants.ANY_VALUE,
+ CommonConstants.CHECK_KEY, String.valueOf(false));
+
+ // ConcurrentMap>>
+ private final ConcurrentMap>>
+ registryCache = new ConcurrentHashMap<>();
+ /**
+ * Make sure ID never changed when the same url notified many times
+ */
+ private final ConcurrentHashMap URL_IDS_MAPPER = new ConcurrentHashMap<>();
+
+ public RegistryServerSync() {
+ }
+
+ public ConcurrentMap>> getRegistryCache() {
+ return registryCache;
+ }
+
+ @Override
+ public void notify(List urls) {
+ if (urls == null || urls.isEmpty()) {
+ return;
+ }
+ // Map>>
+ final Map>> categories = new HashMap<>();
+ String interfaceName = null;
+ for (URL url : urls) {
+ String category = url.getParameter(RegistryConstants.CATEGORY_KEY, RegistryConstants.PROVIDERS_CATEGORY);
+ if (RegistryConstants.EMPTY_PROTOCOL.equalsIgnoreCase(url.getProtocol())) { // NOTE: group and version in empty protocol is *
+ ConcurrentMap> services = registryCache.get(category);
+ if (services != null) {
+ String group = url.getParameter(CommonConstants.GROUP_KEY);
+ String version = url.getParameter(CommonConstants.VERSION_KEY);
+ // NOTE: group and version in empty protocol is *
+ if (!CommonConstants.ANY_VALUE.equals(group) && !CommonConstants.ANY_VALUE.equals(version)) {
+ services.remove(url.getServiceKey());
+ } else {
+ for (Map.Entry> serviceEntry : services.entrySet()) {
+ String service = serviceEntry.getKey();
+ if (this.getInterface(service).equals(url.getServiceInterface())
+ && (CommonConstants.ANY_VALUE.equals(group) || StringUtils.isEquals(group, this.getGroup(service)))
+ && (CommonConstants.ANY_VALUE.equals(version) || StringUtils.isEquals(version, this.getVersion(service)))) {
+ services.remove(service);
+ }
+ }
+ }
+ }
+ } else {
+ if (StringUtils.isEmpty(interfaceName)) {
+ interfaceName = url.getServiceInterface();
+ }
+ Map> services = categories.get(category);
+ if (services == null) {
+ services = new HashMap<>();
+ categories.put(category, services);
+ }
+ String service = url.getServiceKey();
+ Map ids = services.get(service);
+ if (ids == null) {
+ ids = new HashMap<>();
+ services.put(service, ids);
+ }
+
+ // Make sure we use the same ID for the same URL
+ if (URL_IDS_MAPPER.containsKey(url.toFullString())) {
+ ids.put(URL_IDS_MAPPER.get(url.toFullString()), url);
+ } else {
+ String md5 = MD5Util.MD5_16bit(url.toFullString());
+ ids.put(md5, url);
+ URL_IDS_MAPPER.putIfAbsent(url.toFullString(), md5);
+ }
+ }
+ }
+ if (categories.size() == 0) {
+ return;
+ }
+ for (Map.Entry>> categoryEntry : categories.entrySet()) {
+ String category = categoryEntry.getKey();
+ ConcurrentMap> services = registryCache.get(category);
+ if (services == null) {
+ services = new ConcurrentHashMap>();
+ registryCache.put(category, services);
+ } else {// Fix map can not be cleared when service is unregistered: when a unique “group/service:version” service is unregistered, but we still have the same services with different version or group, so empty protocols can not be invoked.
+ Set keys = new HashSet(services.keySet());
+ for (String key : keys) {
+ if (this.getInterface(key).equals(interfaceName) && !categoryEntry.getValue().entrySet().contains(key)) {
+ services.remove(key);
+ }
+ }
+ }
+ services.putAll(categoryEntry.getValue());
+ }
+ }
+
+ public String getInterface(String service) {
+ if (service != null && service.length() > 0) {
+ int i = service.indexOf('/');
+ if (i >= 0) {
+ service = service.substring(i + 1);
+ }
+ i = service.lastIndexOf(':');
+ if (i >= 0) {
+ service = service.substring(0, i);
+ }
+ }
+ return service;
+ }
+
+ public String getGroup(String service) {
+ if (service != null && service.length() > 0) {
+ int i = service.indexOf('/');
+ if (i >= 0) {
+ return service.substring(0, i);
+ }
+ }
+ return null;
+ }
+
+ public String getVersion(String service) {
+ if (service != null && service.length() > 0) {
+ int i = service.lastIndexOf(':');
+ if (i >= 0) {
+ return service.substring(i + 1);
+ }
+ }
+ return null;
+ }
+}
diff --git a/backend/src/main/java/io/metersphere/api/dubbo/utils/Constants.java b/backend/src/main/java/io/metersphere/api/dubbo/utils/Constants.java
new file mode 100644
index 0000000000..16ff47dc56
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dubbo/utils/Constants.java
@@ -0,0 +1,614 @@
+/*
+ * 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 io.metersphere.api.dubbo.utils;
+
+import io.metersphere.api.dubbo.MethodArgument;
+import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.testelement.property.IntegerProperty;
+import org.apache.jmeter.testelement.property.StringProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Constants
+ */
+public class Constants {
+
+ //Registry Protocol
+ public static final String REGISTRY_NONE = "none";
+ public static final String REGISTRY_ZOOKEEPER = "zookeeper";
+ public static final String REGISTRY_NACOS = "nacos";
+ public static final String APOLLO = "apollo";
+ public static final String REGISTRY_MULTICAST = "multicast";
+ public static final String REGISTRY_REDIS = "redis";
+ public static final String REGISTRY_SIMPLE = "simple";
+
+ //RPC Protocol
+ public static final String RPC_PROTOCOL_DUBBO = "dubbo";
+ public static final String RPC_PROTOCOL_RMI = "rmi";
+ public static final String RPC_PROTOCOL_HESSIAN = "hessian";
+ public static final String RPC_PROTOCOL_HTTP = "http";
+ public static final String RPC_PROTOCOL_WEBSERVICE = "webservice";
+ public static final String RPC_PROTOCOL_THRIFT = "thrift";
+ public static final String RPC_PROTOCOL_MEMCACHED = "memcached";
+ public static final String RPC_PROTOCOL_REDIS = "redis";
+
+ public static final String ASYNC = "async";
+ public static final String SYMBOL = "://";
+
+ public static final int INT_DEFAULT = 0;
+ public static final double DOUBLE_DEFAULT = 0.0d;
+ public static final boolean BOOLEAN_DEFAULT = false;
+ public static final char CHAR_DEFAULT = '\u0000';
+ public static final float FLOAT_DEFAULT = 0.0f;
+ public static final byte BYTE_DEFAULT = 0;
+ public static final long LONG_DEFAULT = 0l;
+ public static final short SHORT_DEFAULT = 0;
+ public static final int[] INT_ARRAY_DEFAULT = null;
+ public static final double[] DOUBLE_ARRAY_DEFAULT = null;
+ public static final boolean[] BOOLEAN_ARRAY_DEFAULT = null;
+ public static final char[] CHAT_ARRAY_DEFAULT = null;
+ public static final float[] FLOAT_ARRAY_DEFAULT = null;
+ public static final byte[] BYTE_ARRAY_DEFAULT = null;
+ public static final long[] LONG_ARRAY_DEFAULT = null;
+ public static final short[] SHORT_ARRAY_DEFAULT = null;
+
+ public static final String FIELD_DUBBO_REGISTRY_PROTOCOL = "FIELD_DUBBO_REGISTRY_PROTOCOL";
+ public static final String FIELD_DUBBO_REGISTRY_GROUP = "FIELD_DUBBO_REGISTRY_GROUP";
+ public static final String FIELD_DUBBO_REGISTRY_USER_NAME = "FIELD_DUBBO_REGISTRY_USER_NAME";
+ public static final String FIELD_DUBBO_REGISTRY_PASSWORD = "FIELD_DUBBO_REGISTRY_PASSWORD";
+ public static final String FIELD_DUBBO_REGISTRY_TIMEOUT = "FIELD_DUBBO_REGISTRY_TIMEOUT";
+ public static final String FIELD_DUBBO_CONFIG_CENTER_PROTOCOL = "FIELD_DUBBO_CONFIG_CENTER_PROTOCOL";
+ public static final String FIELD_DUBBO_CONFIG_CENTER_GROUP = "FIELD_DUBBO_CONFIG_CENTER_GROUP";
+ public static final String FIELD_DUBBO_CONFIG_CENTER_NAMESPACE = "FIELD_DUBBO_CONFIG_CENTER_NAMESPACE";
+ public static final String FIELD_DUBBO_CONFIG_CENTER_USER_NAME = "FIELD_DUBBO_CONFIG_CENTER_USER_NAME";
+ public static final String FIELD_DUBBO_CONFIG_CENTER_PASSWORD = "FIELD_DUBBO_CONFIG_CENTER_PASSWORD";
+ public static final String FIELD_DUBBO_CONFIG_CENTER_TIMEOUT = "FIELD_DUBBO_CONFIG_CENTER_TIMEOUT";
+ public static final String FIELD_DUBBO_CONFIG_CENTER_ADDRESS = "FIELD_DUBBO_CONFIG_CENTER_ADDRESS";
+ public static final String FIELD_DUBBO_RPC_PROTOCOL = "FIELD_DUBBO_RPC_PROTOCOL";
+ public static final String FIELD_DUBBO_ADDRESS = "FIELD_DUBBO_ADDRESS";
+ public static final String FIELD_DUBBO_TIMEOUT = "FIELD_DUBBO_TIMEOUT";
+ public static final String FIELD_DUBBO_VERSION = "FIELD_DUBBO_VERSION";
+ public static final String FIELD_DUBBO_RETRIES = "FIELD_DUBBO_RETRIES";
+ public static final String FIELD_DUBBO_CLUSTER = "FIELD_DUBBO_CLUSTER";
+ public static final String FIELD_DUBBO_GROUP = "FIELD_DUBBO_GROUP";
+ public static final String FIELD_DUBBO_CONNECTIONS = "FIELD_DUBBO_CONNECTIONS";
+ public static final String FIELD_DUBBO_LOADBALANCE = "FIELD_DUBBO_LOADBALANCE";
+ public static final String FIELD_DUBBO_ASYNC = "FIELD_DUBBO_ASYNC";
+ public static final String FIELD_DUBBO_INTERFACE = "FIELD_DUBBO_INTERFACE";
+ 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";
+ public static final String DEFAULT_CLUSTER = "failfast";
+ public static final String DEFAULT_CONNECTIONS = "100";
+
+ //冗余配置元件中的address、protocols、group,用于在sample gui获取配置元件中的默认值
+ public static String DEFAULT_PANEL_ADDRESS = "";
+ public static String DEFAULT_PANEL_PROTOCOLS = "";
+ public static String DEFAULT_PANEL_GROUP = "";
+
+ public static final void redundancy(TestElement element) {
+ DEFAULT_PANEL_ADDRESS = Constants.getAddress(element);
+ DEFAULT_PANEL_PROTOCOLS = Constants.getRegistryProtocol(element);
+ DEFAULT_PANEL_GROUP = Constants.getRegistryGroup(element);
+ }
+
+ /**
+ * get Registry Protocol
+ *
+ * @return the protocol
+ */
+ public static final String getRegistryProtocol(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_REGISTRY_PROTOCOL);
+ }
+
+ /**
+ * set Registry Protocol
+ *
+ * @param registryProtocol the protocol to set
+ */
+ public static final void setRegistryProtocol(String registryProtocol, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_REGISTRY_PROTOCOL, StringUtils.trimAllWhitespace(registryProtocol)));
+ }
+
+ /**
+ * get Registry Group
+ *
+ * @return the group
+ */
+ public static final String getRegistryGroup(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_REGISTRY_GROUP);
+ }
+
+ /**
+ * set Registry Group
+ *
+ * @param registryGroup the group to set
+ */
+ public static final void setRegistryGroup(String registryGroup, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_REGISTRY_GROUP, StringUtils.trimAllWhitespace(registryGroup)));
+ }
+
+ /**
+ * get Registry username
+ *
+ * @return the username
+ */
+ public static final String getRegistryUserName(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_REGISTRY_USER_NAME);
+ }
+
+ /**
+ * set Registry username
+ *
+ * @param username the username to set
+ */
+ public static final void setRegistryUserName(String username, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_REGISTRY_USER_NAME, StringUtils.trimAllWhitespace(username)));
+ }
+
+ /**
+ * get Registry password
+ *
+ * @return the password
+ */
+ public static final String getRegistryPassword(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_REGISTRY_PASSWORD);
+ }
+
+ /**
+ * set Registry password
+ *
+ * @param password the password to set
+ */
+ public static final void setRegistryPassword(String password, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_REGISTRY_PASSWORD, StringUtils.trimAllWhitespace(password)));
+ }
+
+ /**
+ * get Registry timeout
+ *
+ * @return the timeout
+ */
+ public static final String getRegistryTimeout(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_REGISTRY_TIMEOUT);
+ }
+
+ /**
+ * set Registry timeout
+ *
+ * @param timeout the group to set
+ */
+ public static final void setRegistryTimeout(String timeout, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_REGISTRY_TIMEOUT, StringUtils.trimAllWhitespace(timeout)));
+ }
+
+ /**
+ * get ConfigCenter protocol
+ *
+ * @return the protocol
+ */
+ public static final String getConfigCenterProtocol(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CONFIG_CENTER_PROTOCOL);
+ }
+
+ /**
+ * set ConfigCenter protocol
+ *
+ * @param protocol the protocol to set
+ */
+ public static final void setConfigCenterProtocol(String protocol, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CONFIG_CENTER_PROTOCOL, StringUtils.trimAllWhitespace(protocol)));
+ }
+
+ /**
+ * get ConfigCenter group
+ *
+ * @return the group
+ */
+ public static final String getConfigCenterGroup(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CONFIG_CENTER_GROUP);
+ }
+
+ /**
+ * set ConfigCenter group
+ *
+ * @param group the group to set
+ */
+ public static final void setConfigCenterGroup(String group, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CONFIG_CENTER_GROUP, StringUtils.trimAllWhitespace(group)));
+ }
+
+ /**
+ * get ConfigCenter namespace
+ *
+ * @return the namespace
+ */
+ public static final String getConfigCenterNamespace(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CONFIG_CENTER_NAMESPACE);
+ }
+
+ /**
+ * set ConfigCenter namespace
+ *
+ * @param namespace the namespace to set
+ */
+ public static final void setConfigCenterNamespace(String namespace, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CONFIG_CENTER_NAMESPACE, StringUtils.trimAllWhitespace(namespace)));
+ }
+
+ /**
+ * get ConfigCenter username
+ *
+ * @return the username
+ */
+ public static final String getConfigCenterUserName(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CONFIG_CENTER_USER_NAME);
+ }
+
+ /**
+ * set ConfigCenter username
+ *
+ * @param username the username to set
+ */
+ public static final void setConfigCenterUserName(String username, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CONFIG_CENTER_USER_NAME, StringUtils.trimAllWhitespace(username)));
+ }
+
+ /**
+ * get ConfigCenter password
+ *
+ * @return the password
+ */
+ public static final String getConfigCenterPassword(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CONFIG_CENTER_PASSWORD);
+ }
+
+ /**
+ * set ConfigCenter password
+ *
+ * @param password the password to set
+ */
+ public static final void setConfigCenterPassword(String password, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CONFIG_CENTER_PASSWORD, StringUtils.trimAllWhitespace(password)));
+ }
+
+ /**
+ * get ConfigCenter address
+ *
+ * @return the address
+ */
+ public static final String getConfigCenterAddress(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CONFIG_CENTER_ADDRESS);
+ }
+
+ /**
+ * set ConfigCenter namespace
+ *
+ * @param address the address to set
+ */
+ public static final void setConfigCenterAddress(String address, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CONFIG_CENTER_ADDRESS, StringUtils.trimAllWhitespace(address)));
+ }
+
+ /**
+ * get ConfigCenter timeout
+ *
+ * @return the timeout
+ */
+ public static final String getConfigCenterTimeout(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CONFIG_CENTER_TIMEOUT);
+ }
+
+ /**
+ * set ConfigCenter namespace
+ *
+ * @param timeout the timeout to set
+ */
+ public static final void setConfigCenterTimeout(String timeout, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CONFIG_CENTER_TIMEOUT, StringUtils.trimAllWhitespace(timeout)));
+ }
+
+ /**
+ * get RPC protocol
+ *
+ * @return the RPC protocol
+ */
+ public static final String getRpcProtocol(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_RPC_PROTOCOL);
+ }
+
+ /**
+ * set RPC protocol
+ *
+ * @param rpcProtocol the protocol to set
+ */
+ public static final void setRpcProtocol(String rpcProtocol, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_RPC_PROTOCOL, StringUtils.trimAllWhitespace(rpcProtocol)));
+ }
+
+ /**
+ * get address
+ *
+ * @return the address
+ */
+ public static final String getAddress(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_ADDRESS);
+ }
+
+ /**
+ * set address
+ *
+ * @param address the address to set
+ */
+ public static final void setAddress(String address, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_ADDRESS, StringUtils.trimAllWhitespace(address)));
+ }
+
+ /**
+ * get timeout
+ *
+ * @return the timeout
+ */
+ public static final String getTimeout(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_TIMEOUT, DEFAULT_TIMEOUT);
+ }
+
+ /**
+ * set timeout
+ *
+ * @param timeout the timeout to set
+ */
+ public static final void setTimeout(String timeout, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_TIMEOUT, StringUtils.trimAllWhitespace(timeout)));
+ }
+
+ /**
+ * get version
+ *
+ * @return the version
+ */
+ public static final String getVersion(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_VERSION, DEFAULT_VERSION);
+ }
+
+ /**
+ * set version
+ *
+ * @param version the version to set
+ */
+ public static final void setVersion(String version, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_VERSION, StringUtils.trimAllWhitespace(version)));
+ }
+
+ /**
+ * get retries
+ *
+ * @return the retries
+ */
+ public static final String getRetries(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_RETRIES, DEFAULT_RETRIES);
+ }
+
+ /**
+ * set retries
+ *
+ * @param retries the retries to set
+ */
+ public static final void setRetries(String retries, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_RETRIES, StringUtils.trimAllWhitespace(retries)));
+ }
+
+ /**
+ * get cluster
+ *
+ * @return the cluster
+ */
+ public static final String getCluster(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CLUSTER, DEFAULT_CLUSTER);
+ }
+
+ /**
+ * set cluster
+ *
+ * @param cluster the cluster to set
+ */
+ public static final void setCluster(String cluster, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CLUSTER, StringUtils.trimAllWhitespace(cluster)));
+ }
+
+ /**
+ * get group
+ *
+ * @return the group
+ */
+ public static final String getGroup(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_GROUP, null);
+ }
+
+ /**
+ * set group
+ *
+ * @param group the group to set
+ */
+ public static final void setGroup(String group, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_GROUP, StringUtils.trimAllWhitespace(group)));
+ }
+
+ /**
+ * get connections
+ *
+ * @return the group
+ */
+ public static final String getConnections(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_CONNECTIONS, DEFAULT_CONNECTIONS);
+ }
+
+ /**
+ * set connections
+ *
+ * @param connections the connections to set
+ */
+ public static final void setConnections(String connections, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_CONNECTIONS, StringUtils.trimAllWhitespace(connections)));
+ }
+
+ /**
+ * get loadbalance
+ *
+ * @return the loadbalance
+ */
+ public static final String getLoadbalance(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_LOADBALANCE);
+ }
+
+ /**
+ * set loadbalance
+ *
+ * @param loadbalance the loadbalance to set
+ */
+ public static final void setLoadbalance(String loadbalance, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_LOADBALANCE, StringUtils.trimAllWhitespace(loadbalance)));
+ }
+
+ /**
+ * get async
+ *
+ * @return the async
+ */
+ public static final String getAsync(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_ASYNC);
+ }
+
+ /**
+ * set async
+ *
+ * @param async the async to set
+ */
+ public static final void setAsync(String async, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_ASYNC, StringUtils.trimAllWhitespace(async)));
+ }
+
+ /**
+ * get interfaceName
+ *
+ * @return the interfaceName
+ */
+ public static final String getInterface(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_INTERFACE);
+ }
+
+ /**
+ * set interfaceName
+ *
+ * @param interfaceName the interfaceName to set
+ */
+ public static final void setInterfaceName(String interfaceName, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_INTERFACE, StringUtils.trimAllWhitespace(interfaceName)));
+ }
+
+ /**
+ * get method
+ *
+ * @return the method
+ */
+ public static final String getMethod(TestElement element) {
+ return element.getPropertyAsString(FIELD_DUBBO_METHOD);
+ }
+
+ /**
+ * set method
+ *
+ * @param method the method to set
+ */
+ public static final void setMethod(String method, TestElement element) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_METHOD, StringUtils.trimAllWhitespace(method)));
+ }
+
+ /**
+ * get methodArgs
+ *
+ * @return the methodArgs
+ */
+ public static final List getMethodArgs(TestElement element) {
+ int paramsSize = element.getPropertyAsInt(FIELD_DUBBO_METHOD_ARGS_SIZE, 0);
+ List list = new ArrayList();
+ for (int i = 1; i <= paramsSize; i++) {
+ String paramType = element.getPropertyAsString(FIELD_DUBBO_METHOD_ARGS + "_PARAM_TYPE" + i);
+ String paramValue = element.getPropertyAsString(FIELD_DUBBO_METHOD_ARGS + "_PARAM_VALUE" + i);
+ MethodArgument args = new MethodArgument(paramType, paramValue);
+ list.add(args);
+ }
+ return list;
+ }
+
+ /**
+ * set methodArgs
+ *
+ * @param methodArgs the methodArgs to set
+ */
+ public static final void setMethodArgs(List methodArgs, TestElement element) {
+ int size = methodArgs == null ? 0 : methodArgs.size();
+ element.setProperty(new IntegerProperty(FIELD_DUBBO_METHOD_ARGS_SIZE, size));
+ if (size > 0) {
+ for (int i = 1; i <= methodArgs.size(); i++) {
+ element.setProperty(new StringProperty(FIELD_DUBBO_METHOD_ARGS + "_PARAM_TYPE" + i, methodArgs.get(i - 1).getParamType()));
+ element.setProperty(new StringProperty(FIELD_DUBBO_METHOD_ARGS + "_PARAM_VALUE" + i, methodArgs.get(i - 1).getParamValue()));
+ }
+ }
+ }
+
+ /**
+ * 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/backend/src/main/java/io/metersphere/api/dubbo/utils/JsonUtils.java b/backend/src/main/java/io/metersphere/api/dubbo/utils/JsonUtils.java
new file mode 100644
index 0000000000..e3022ab121
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dubbo/utils/JsonUtils.java
@@ -0,0 +1,52 @@
+package io.metersphere.api.dubbo.utils;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Type;
+
+/**
+ * JsonUtils
+ */
+public class JsonUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);
+
+ private static final Gson gson = new GsonBuilder()
+ .setDateFormat("yyyy-MM-dd HH:mm:ss")
+ .setPrettyPrinting()
+ .disableHtmlEscaping()
+ .serializeNulls()
+ .create();
+
+ public static String toJson(Object obj) {
+ return gson.toJson(obj);
+ }
+
+ public static String toJson(Object obj, Type type) {
+ return gson.toJson(obj, type);
+ }
+
+ public static T formJson(String json, Class classOfT) {
+ try {
+ return gson.fromJson(json, classOfT);
+ } catch (JsonSyntaxException e) {
+ logger.error("json to class[" + classOfT.getName() + "] is error!",
+ e);
+ }
+ return null;
+ }
+
+ public static T formJson(String json, Type type) {
+ try {
+ return gson.fromJson(json, type);
+ } catch (JsonSyntaxException e) {
+ logger.error("json to class[" + type.getClass().getName()
+ + "] is error!", e);
+ }
+ return null;
+ }
+}
diff --git a/backend/src/main/java/io/metersphere/api/dubbo/utils/MD5Util.java b/backend/src/main/java/io/metersphere/api/dubbo/utils/MD5Util.java
new file mode 100644
index 0000000000..23786ab5fd
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dubbo/utils/MD5Util.java
@@ -0,0 +1,65 @@
+/*
+ * 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 io.metersphere.api.dubbo.utils;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * MD5Util
+ */
+public class MD5Util {
+ private static MessageDigest md;
+ private static final char[] hexCode = "0123456789ABCDEF".toCharArray();
+
+ static {
+ try {
+ md = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static String MD5_16bit(String input) {
+ String hash = MD5_32bit(input);
+ if (hash == null) {
+ return null;
+ }
+ return hash.substring(8, 24);
+ }
+
+ public static String MD5_32bit(String input) {
+ if (input == null || input.length() == 0) {
+ return null;
+ }
+ md.update(input.getBytes());
+ byte[] digest = md.digest();
+ String hash = convertToString(digest);
+ return hash;
+ }
+
+ private static String convertToString(byte[] data) {
+ StringBuilder r = new StringBuilder(data.length * 2);
+ for (byte b : data) {
+ r.append(hexCode[(b >> 4) & 0xF]);
+ r.append(hexCode[(b & 0xF)]);
+ }
+ return r.toString();
+ }
+
+}
diff --git a/backend/src/main/java/io/metersphere/api/dubbo/utils/StringUtils.java b/backend/src/main/java/io/metersphere/api/dubbo/utils/StringUtils.java
new file mode 100644
index 0000000000..5f9f4814d2
--- /dev/null
+++ b/backend/src/main/java/io/metersphere/api/dubbo/utils/StringUtils.java
@@ -0,0 +1,69 @@
+package io.metersphere.api.dubbo.utils;
+
+/**
+ * StringUtils
+ */
+public class StringUtils {
+
+ public static boolean hasLength(String str) {
+ return str != null && !str.isEmpty();
+ }
+
+ public static String trimAllWhitespace(String str) {
+ if (!hasLength(str)) {
+ return str;
+ } else {
+ int len = str.length();
+ StringBuilder sb = new StringBuilder(str.length());
+
+ for (int i = 0; i < len; ++i) {
+ char c = str.charAt(i);
+ if (!Character.isWhitespace(c)) {
+ sb.append(c);
+ }
+ }
+
+ return sb.toString();
+ }
+ }
+
+ public static String trimWhitespace(String str) {
+ if (!hasLength(str)) {
+ return str;
+ } else {
+ StringBuilder sb = new StringBuilder(str);
+
+ while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
+ sb.deleteCharAt(0);
+ }
+
+ while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
+ sb.deleteCharAt(sb.length() - 1);
+ }
+
+ return sb.toString();
+ }
+ }
+
+ public static boolean isBlank(CharSequence cs) {
+ int strLen;
+ if (cs != null && (strLen = cs.length()) != 0) {
+ for (int i = 0; i < strLen; ++i) {
+ if (!Character.isWhitespace(cs.charAt(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ return true;
+ }
+ }
+
+ public static boolean isBlank1(String paramValue) {
+ if (isBlank(paramValue) || "null".equals(paramValue.toLowerCase())) {
+ return true;
+ }
+ return false;
+ }
+}