From 954b1114fd98cd7778a1a0d1c96d82e5c8c595d2 Mon Sep 17 00:00:00 2001 From: xuwangcheng Date: Sun, 24 Jan 2021 15:03:31 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=9C=A8=E7=BB=84=E5=90=88=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=E4=B8=AD=E7=9A=84=E6=9B=BF=E6=8D=A2=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=B8=AD=EF=BC=8C=E6=94=AF=E6=8C=81=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=85=A8=E5=B1=80=E5=8F=98=E9=87=8F=E3=80=81=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=B1=A0=E5=8F=98=E9=87=8F=E3=80=81=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=9B=86=E5=85=AC=E5=85=B1=E5=8F=98=E9=87=8F=EF=BC=88=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=A0=BC=E5=BC=8F=E4=B8=BA=EF=BC=9A${=5F=5F=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=90=8D}=EF=BC=89=E3=80=81=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E5=8F=98=E9=87=8F=EF=BC=88=E4=BD=BF=E7=94=A8=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E4=B8=BA=EF=BC=9A${=E5=8F=98=E9=87=8F=E5=90=8D}?= =?UTF-8?q?=EF=BC=89=E4=BB=A5=E5=8F=8A=E5=B8=B8=E9=87=8F=EF=BC=8C=E4=B8=94?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=87=AA=E7=94=B1=E7=BB=84=E5=90=88=E6=94=BE?= =?UTF-8?q?=E5=9C=A8=E4=B8=80=E8=B5=B7=E4=BD=BF=E7=94=A8=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=97=B6=E6=B3=A8=E6=84=8F=E5=8F=98=E9=87=8F=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E7=9A=84=E4=BC=98=E5=85=88=E7=BA=A7=E5=8D=B3=E5=8F=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/yi/master/constant/MessageKeys.java | 5 ++ .../message/test/MessageAutoTest.java | 55 ++++++++++++------- .../java/yi/master/util/PracticalUtils.java | 33 +++++++++++ .../webapp/resource/message/messageScene.js | 2 +- update.md | 5 ++ 5 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/main/java/yi/master/constant/MessageKeys.java b/src/main/java/yi/master/constant/MessageKeys.java index aa963f5..4b848b9 100644 --- a/src/main/java/yi/master/constant/MessageKeys.java +++ b/src/main/java/yi/master/constant/MessageKeys.java @@ -304,6 +304,11 @@ public interface MessageKeys { String CUSTOM_PARAMETER_BOUNDARY_SYMBOL_LEFT = "#"; String CUSTOM_PARAMETER_BOUNDARY_SYMBOL_RIGHT = "#"; + /** + * 组合场景内使用上下文变量的左右变量 + */ + String COMPLEX_SCENE_USE_VARIABLE_BOUNDARY_SYMBOL_LEFT = "${"; + String COMPLEX_SCENE_USE_VARIABLE_BOUNDARY_SYMBOL_RIGHT = "}"; /** * quartz定时任务执行的测试将会在对应的测试报告添加下面的备注 diff --git a/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java b/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java index e66a5f9..f81d20a 100644 --- a/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java +++ b/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java @@ -1,6 +1,7 @@ package yi.master.coretest.message.test; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.StrUtil; import net.sf.json.JSONObject; @@ -36,7 +37,6 @@ import yi.master.util.cache.CacheUtil; import java.sql.Timestamp; import java.util.*; -import java.util.regex.Pattern; @@ -426,16 +426,16 @@ public class MessageAutoTest { , String complexSceneName, List results, boolean async) { //替换上下文变量 for (Map.Entry entry:scene.getScene().getConfig().getUseVariables().entrySet()) { - String value = null; - if (saveVariables.containsKey(entry.getValue())) { - //如果有对应上下文替换变量的就替换掉,否则使用常量 - value = saveVariables.get(entry.getValue()); - } else { - value = entry.getValue(); - } + String value = PracticalUtils.replaceComplexSceneUseVariable(entry.getValue(), saveVariables); +// if (saveVariables.containsKey(entry.getValue())) { +// //如果有对应上下文替换变量的就替换掉,否则使用常量 +// value = saveVariables.get(entry.getValue()); +// } else { +// value = entry.getValue(); +// } if (scene.getCallParameter() == null) { - scene.setCallParameter(new HashMap()); + scene.setCallParameter(new HashMap<>()); scene.getCallParameter().put(MessageKeys.HTTP_PARAMETER_HEADER, new HashMap()); } if (scene.getCallParameter().get(MessageKeys.HTTP_PARAMETER_QUERYS) == null) { @@ -449,9 +449,9 @@ public class MessageAutoTest { } else if (entry.getKey().startsWith("Querys.")) { ((Map) scene.getCallParameter().get(MessageKeys.HTTP_PARAMETER_QUERYS)).put(entry.getKey().substring(entry.getKey().indexOf(".") + 1) , value); + // 否则就是替换入参 } else { - scene.setRequestMessage(scene.getRequestMessage().replace(MessageKeys.CUSTOM_PARAMETER_BOUNDARY_SYMBOL_LEFT + - entry.getValue() + MessageKeys.CUSTOM_PARAMETER_BOUNDARY_SYMBOL_RIGHT, value)); + scene.setRequestMessage(scene.getRequestMessage().replace(entry.getValue(), value)); } //处理可能存在的路径参数 @@ -816,33 +816,46 @@ public class MessageAutoTest { } JSONObject paramsData = JSONObject.fromObject(StringUtils.isNotBlank(d.getParamsData()) ? d.getParamsData() : "{}"); + //有单独的测试配置说明是组合场景下的场景 if (scene.getConfig() != null) { for (Map.Entry entry:scene.getConfig().getUseVariables().entrySet()) { String replaceVariable = entry.getValue(); - if (!Pattern.matches("\\$\\{__(.*?)\\}", replaceVariable)) { - //如果不是全局变量说明是常量或者上下文保存的测试结果变量 - replaceVariable = MessageKeys.CUSTOM_PARAMETER_BOUNDARY_SYMBOL_LEFT + replaceVariable + MessageKeys.CUSTOM_PARAMETER_BOUNDARY_SYMBOL_RIGHT; - } + // 如果里面有全局变量就替换 + replaceVariable = PracticalUtils.replaceGlobalVariable(replaceVariable, globalVariableService); + + // 如果里面有数据池变量就替换 + replaceVariable = PracticalUtils.replacePoolData(replaceVariable, poolData.get(itemId)); + + // 如果里面有测试集公共变量就替换 + replaceVariable = PracticalUtils.replaceSetPublicVariable(replaceVariable, config.getPublicDataObject()); + + // 剩下就是在测试过程中需要替换的上下文变量 + // 放到替换入参的参数中 paramsData.put(MessageKeys.MESSAGE_PARAMETER_DEFAULT_ROOT_PATH + "." + entry.getKey(), replaceVariable); + scene.getConfig().getUseVariables().put(entry.getKey(), replaceVariable); } } - //替换入参报文中的测试集公共变量 - requestMessage = PracticalUtils.replaceSetPublicVariable(parseUtil.depacketizeMessageToString(msg.getComplexParameter() - , paramsData.toString()), config.getPublicDataObject()); + + requestMessage = parseUtil.depacketizeMessageToString(msg.getComplexParameter(), paramsData.toString()); } + //替换入参报文中的全局变量 + requestMessage = PracticalUtils.replaceGlobalVariable(requestMessage, globalVariableService); + // 处理数据池 if (itemId != null) { testScene.setPoolDataItemId(itemId); testScene.setPoolData(poolData.get(itemId)); - // 替换数据池里的数据 + // 替换入参报文中数据池里的数据 requestMessage = PracticalUtils.replacePoolData(requestMessage, testScene.getPoolData()); } - //替换入参报文中的全局变量 - requestMessage = PracticalUtils.replaceGlobalVariable(requestMessage, globalVariableService); + //替换入参报文中的测试集公共变量 + if (MapUtil.isNotEmpty(config.getPublicDataObject())) { + requestMessage = PracticalUtils.replaceSetPublicVariable(requestMessage, config.getPublicDataObject()); + } //处理请求URL中的全局变量 requestUrl = PracticalUtils.replaceGlobalVariable(requestUrl, globalVariableService); diff --git a/src/main/java/yi/master/util/PracticalUtils.java b/src/main/java/yi/master/util/PracticalUtils.java index 8c6afd9..02f75ac 100644 --- a/src/main/java/yi/master/util/PracticalUtils.java +++ b/src/main/java/yi/master/util/PracticalUtils.java @@ -719,6 +719,39 @@ public class PracticalUtils { return requestUrl; } + /** + * 替换组合场景中的上下文变量 + * @author xuwangcheng + * @date 2021/1/24 14:20 + * @param msg msg + * @param saveVariables saveVariables + * @return {@link String} + */ + public static String replaceComplexSceneUseVariable(String msg, Map saveVariables) { + if (StringUtils.isBlank(msg)) { + return msg; + } + + String regex = "\\$\\{(.*?)\\}"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(msg); + + String value = null; + String useVariable = null; + while (matcher.find()) { + useVariable = "${" + matcher.group(1) + "}"; + if (!msg.contains(useVariable)) { + continue; + } + value = saveVariables.get(matcher.group(1)); + if (value == null) { + continue; + } + msg = msg.replace(useVariable, value); + } + return msg; + } + /** * 替换测试集公共数据变量 * @author xuwangcheng diff --git a/src/main/webapp/resource/message/messageScene.js b/src/main/webapp/resource/message/messageScene.js index 9dd273f..b3d3487 100644 --- a/src/main/webapp/resource/message/messageScene.js +++ b/src/main/webapp/resource/message/messageScene.js @@ -463,7 +463,7 @@ var eventList = { success:function (json) { if (json.returnCode == 0) { showSelectBox(json.data, "id", "id", function(id, object, index){ - $("#scene-variables-value").val(id); + $("#scene-variables-value").val("${" + id + "}"); layer.close(index); }); } else { diff --git a/update.md b/update.md index a9124e0..38900a2 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,8 @@ +### v1.1.2(未发布) +#### 2021.01.24 +- 在组合场景中的替换变量配置中,支持使用全局变量、数据池变量、测试集公共变量(使用格式为:${__变量名})、上下文变量(使用格式为:${变量名})以及常量,且可以自由组合放在一起使用,使用时注意变量替换的优先级即可; + + ### v1.1.1 #### 2021.01.13 - 增加几个定制化的报文处理器; -- Gitee From 2514903bc5c9a74c227d861f9beb79ef600e1123 Mon Sep 17 00:00:00 2001 From: xuwangcheng Date: Sat, 30 Jan 2021 18:41:44 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E4=B8=8A=E5=8F=AF=E4=BB=A5=E9=85=8D=E7=BD=AE=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81HTTP/HTTPS?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/message/bean/TestResult.hbm.xml | 3 + .../business/message/bean/TestResult.java | 15 +++- .../testconfig/bean/BusinessSystem.hbm.xml | 15 ++++ .../testconfig/bean/BusinessSystem.java | 81 ++++++++++++++++-- .../java/yi/master/constant/SystemConsts.java | 2 +- .../message/protocol/DubboTestClient.java | 9 +- .../message/protocol/HTTPTestClient.java | 85 +++++++++++++++++-- .../message/protocol/SocketTestClient.java | 8 +- .../coretest/message/protocol/TestClient.java | 22 ++--- .../message/protocol/WebSocketTestClient.java | 9 +- .../protocol/WebserviceTestClient.java | 10 ++- .../message/test/MessageAutoTest.java | 18 ++++ .../yi/master/listener/VersionUpdateUtil.java | 1 + src/main/resources/update/1.1.2 | 8 ++ src/main/webapp/js/dcits.js | 13 ++- .../1.14.0/validate-methods.js | 6 ++ .../webapp/resource/setting/businessSystem.js | 72 +++++++++++++++- .../resource/template/customTemplate.htm | 28 +++++- update.md | 6 +- 19 files changed, 361 insertions(+), 50 deletions(-) create mode 100644 src/main/resources/update/1.1.2 diff --git a/src/main/java/yi/master/business/message/bean/TestResult.hbm.xml b/src/main/java/yi/master/business/message/bean/TestResult.hbm.xml index 51e3b81..2ed7462 100644 --- a/src/main/java/yi/master/business/message/bean/TestResult.hbm.xml +++ b/src/main/java/yi/master/business/message/bean/TestResult.hbm.xml @@ -34,6 +34,9 @@ + + + diff --git a/src/main/java/yi/master/business/message/bean/TestResult.java b/src/main/java/yi/master/business/message/bean/TestResult.java index 78cebdf..670feb8 100644 --- a/src/main/java/yi/master/business/message/bean/TestResult.java +++ b/src/main/java/yi/master/business/message/bean/TestResult.java @@ -147,6 +147,10 @@ public class TestResult implements Serializable, Comparable { * 对应数据池类别 */ private PoolDataItem poolDataItem; + /** + * 代理服务器信息 + */ + private String proxyInfo; private String poolName; private String poolItemName; @@ -176,8 +180,15 @@ public class TestResult implements Serializable, Comparable { this.mark = mark; } - - public void setThreadName(String threadName) { + public void setProxyInfo(String proxyInfo) { + this.proxyInfo = proxyInfo; + } + + public String getProxyInfo() { + return proxyInfo; + } + + public void setThreadName(String threadName) { this.threadName = threadName; } diff --git a/src/main/java/yi/master/business/testconfig/bean/BusinessSystem.hbm.xml b/src/main/java/yi/master/business/testconfig/bean/BusinessSystem.hbm.xml index 1aff0fc..5659c54 100644 --- a/src/main/java/yi/master/business/testconfig/bean/BusinessSystem.hbm.xml +++ b/src/main/java/yi/master/business/testconfig/bean/BusinessSystem.hbm.xml @@ -33,6 +33,21 @@ + + + + + + + + + + + + + + + diff --git a/src/main/java/yi/master/business/testconfig/bean/BusinessSystem.java b/src/main/java/yi/master/business/testconfig/bean/BusinessSystem.java index d944783..ff59c5f 100644 --- a/src/main/java/yi/master/business/testconfig/bean/BusinessSystem.java +++ b/src/main/java/yi/master/business/testconfig/bean/BusinessSystem.java @@ -1,17 +1,16 @@ package yi.master.business.testconfig.bean; -import java.io.Serializable; -import java.sql.Timestamp; -import java.util.HashSet; -import java.util.Set; - import org.apache.commons.lang3.StringUtils; import org.apache.struts2.json.annotations.JSON; - import yi.master.annotation.FieldNameMapper; import yi.master.business.message.bean.InterfaceInfo; import yi.master.constant.MessageKeys; +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.Set; + /** * 测试环境信息类 * @author xuwangcheng @@ -72,6 +71,31 @@ public class BusinessSystem implements Serializable { * 默认路径,如果在接口中没有配置路径则使用该路径
使用${name}表示接口名称,${path}表示在接口中或者报文中定义的路径 */ private String defaultPath; + + /** + * 是否使用代理 + */ + private String useProxy; + + /** + * 代理IP + */ + private String proxyHost; + + /** + * 代理端口 + */ + private Integer proxyPort; + + /** + * 代理用户名 + */ + private String proxyUsername; + + /** + * 代理密码 + */ + private String proxyPassword; /** @@ -141,8 +165,49 @@ public class BusinessSystem implements Serializable { return ""; } - - public void setStatus(String status) { + + + public String getUseProxy() { + return useProxy; + } + + public void setUseProxy(String useProxy) { + this.useProxy = useProxy; + } + + public String getProxyHost() { + return proxyHost; + } + + public void setProxyHost(String proxyHost) { + this.proxyHost = proxyHost; + } + + public Integer getProxyPort() { + return proxyPort; + } + + public void setProxyPort(Integer proxyPort) { + this.proxyPort = proxyPort; + } + + public String getProxyUsername() { + return proxyUsername; + } + + public void setProxyUsername(String proxyUsername) { + this.proxyUsername = proxyUsername; + } + + public String getProxyPassword() { + return proxyPassword; + } + + public void setProxyPassword(String proxyPassword) { + this.proxyPassword = proxyPassword; + } + + public void setStatus(String status) { this.status = status; } diff --git a/src/main/java/yi/master/constant/SystemConsts.java b/src/main/java/yi/master/constant/SystemConsts.java index f03cf24..efb30af 100644 --- a/src/main/java/yi/master/constant/SystemConsts.java +++ b/src/main/java/yi/master/constant/SystemConsts.java @@ -13,7 +13,7 @@ public interface SystemConsts { /** * 当前版本号 */ - String VERSION = "1.1.1"; + String VERSION = "1.1.2"; /** diff --git a/src/main/java/yi/master/coretest/message/protocol/DubboTestClient.java b/src/main/java/yi/master/coretest/message/protocol/DubboTestClient.java index 8c8093d..ecce908 100644 --- a/src/main/java/yi/master/coretest/message/protocol/DubboTestClient.java +++ b/src/main/java/yi/master/coretest/message/protocol/DubboTestClient.java @@ -7,6 +7,7 @@ import org.apache.log4j.Logger; import yi.master.business.testconfig.bean.TestConfig; import yi.master.constant.MessageKeys; import yi.master.coretest.message.protocol.entity.ClientTestResponseObject; +import yi.master.coretest.message.test.TestMessageScene; import yi.master.util.PracticalUtils; import java.io.IOException; @@ -40,8 +41,12 @@ public class DubboTestClient extends TestClient { } @Override - public ClientTestResponseObject sendRequest(String requestUrl, String requestMessage, - Map callParameter, TestConfig config, Object client) { + public ClientTestResponseObject sendRequest(TestMessageScene scene, Object client) { + String requestUrl = scene.getRequestUrl(); + String requestMessage = scene.getRequestMessage(); + Map callParameter = scene.getCallParameter(); + TestConfig config = scene.getConfig(); + ClientTestResponseObject responseObject = new ClientTestResponseObject(); responseObject.setStatusCode("false"); diff --git a/src/main/java/yi/master/coretest/message/protocol/HTTPTestClient.java b/src/main/java/yi/master/coretest/message/protocol/HTTPTestClient.java index a40eda4..2fac106 100644 --- a/src/main/java/yi/master/coretest/message/protocol/HTTPTestClient.java +++ b/src/main/java/yi/master/coretest/message/protocol/HTTPTestClient.java @@ -5,16 +5,21 @@ import cn.hutool.core.io.FileUtil; import net.sf.json.JSONObject; import org.apache.commons.lang.StringUtils; import org.apache.http.*; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.*; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.CookiePolicy; +import org.apache.http.conn.params.ConnRouteParams; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.conn.PoolingClientConnectionManager; @@ -25,11 +30,14 @@ import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.log4j.Logger; import org.springframework.http.HttpMethod; +import yi.master.business.testconfig.bean.BusinessSystem; import yi.master.business.testconfig.bean.TestConfig; import yi.master.constant.MessageKeys; +import yi.master.constant.SystemConsts; import yi.master.coretest.message.parse.URLMessageParse; import yi.master.coretest.message.protocol.entity.ClientTestResponseObject; import yi.master.coretest.message.protocol.entity.HttpDeleteWithBody; +import yi.master.coretest.message.test.TestMessageScene; import yi.master.util.PracticalUtils; import javax.net.ssl.SSLContext; @@ -68,7 +76,7 @@ public class HTTPTestClient extends TestClient { private static final String DEFAULT_HTTP_METHOD = HttpMethod.POST.name(); /**可同时存在的最大httpclient数量*/ - private static final int MAX_DEFAULT_HTTP_CLIENT_COUNT = 100; + private static final int MAX_DEFAULT_HTTP_CLIENT_COUNT = 200; /**活跃客户端池*/ private static final List activeClientPool = new ArrayList(); /**可用客户端池*/ @@ -171,7 +179,12 @@ public class HTTPTestClient extends TestClient { @SuppressWarnings({ "resource", "unchecked" }) @Override - public ClientTestResponseObject sendRequest(String requestUrl, String requestMessage, Map callParameter, TestConfig config, Object httpclient) { + public ClientTestResponseObject sendRequest(TestMessageScene scene, Object httpclient) { + String requestUrl = scene.getRequestUrl(); + String requestMessage = scene.getRequestMessage(); + Map callParameter = scene.getCallParameter(); + TestConfig config = scene.getConfig(); + DefaultHttpClient client = null; if (httpclient == null) { client = defaultClient; @@ -233,6 +246,14 @@ public class HTTPTestClient extends TestClient { client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectTimeOut); //读取超时 client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, readTimeOut); + + // 设置代理 + DefaultHttpClient proxyClient = setProxy(requestUrl, scene.getBusinessSystem()); + if (proxyClient != null) { + LOGGER.info("使用代理方式发送请求: proxyHost=" + scene.getBusinessSystem().getProxyHost() + + ",proxyPort=" + scene.getBusinessSystem().getProxyPort()); + client = proxyClient; + } HttpResponse response = null; long useTime = 0; @@ -331,7 +352,11 @@ public class HTTPTestClient extends TestClient { returnMap.setHeaders(headersObject.toString()); returnMap.setUseTime(useTime); - //if (client != defaultClient) availableClientPool.add(client); + // 清除代理设置 + if (proxyClient != null) { + clearProxy(proxyClient); + putBackTestClient(proxyClient); + } return returnMap; } @@ -379,7 +404,8 @@ public class HTTPTestClient extends TestClient { * @return * @throws Exception */ - public Object[] doGet(String host, Map headers, Map querys, String requestMessage, DefaultHttpClient client) + public Object[] doGet(String host, Map headers, Map querys + , String requestMessage, DefaultHttpClient client) throws Exception { if (querys == null) { querys = new HashMap(); @@ -396,6 +422,7 @@ public class HTTPTestClient extends TestClient { request.addHeader(e.getKey(), PracticalUtils.replaceGlobalVariable(e.getValue(), null)); } } + long beginTime = System.currentTimeMillis(); HttpResponse response = client.execute(request); long endTime = System.currentTimeMillis(); @@ -544,5 +571,53 @@ public class HTTPTestClient extends TestClient { } return entity; - } + } + + /** + * 设置代理 + * @author xuwangcheng + * @date 2021/1/30 16:57 + * @param requestUrl requestUrl + * @param system system + * @return + */ + private DefaultHttpClient setProxy (String requestUrl, BusinessSystem system) { + try { + if (system != null && SystemConsts.DefaultBooleanIdentify.TRUE.getNumber().equals(system.getUseProxy())) { + if (StringUtils.isNotBlank(system.getProxyHost()) && system.getProxyPort() != null ) { + DefaultHttpClient client = getHttpClient(); + HttpHost proxy = new HttpHost(system.getProxyHost(), system.getProxyPort(), requestUrl.startsWith("https") ? "https" : "http"); + client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy); + + // 是否需要认证 + if (StringUtils.isNotBlank(system.getProxyUsername()) + && StringUtils.isNotBlank(system.getProxyPassword())) { + CredentialsProvider provider = new BasicCredentialsProvider(); + provider.setCredentials( + new AuthScope(system.getProxyHost(), system.getProxyPort()), + new UsernamePasswordCredentials(system.getProxyUsername(), system.getProxyPassword())); + client.setCredentialsProvider(provider); + } + + return client; + } + } + } catch (Exception e) { + throw new RuntimeException("设置代理出错,请检查环境的代理配置", e); + } + + return null; + } + + /** + * 清除代理 + * @author xuwangcheng + * @date 2021/1/30 16:58 + * @param client client + * @return + */ + private void clearProxy (DefaultHttpClient client) { + client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, null); + client.setCredentialsProvider(null); + } } diff --git a/src/main/java/yi/master/coretest/message/protocol/SocketTestClient.java b/src/main/java/yi/master/coretest/message/protocol/SocketTestClient.java index e2ab65c..ba1e9da 100644 --- a/src/main/java/yi/master/coretest/message/protocol/SocketTestClient.java +++ b/src/main/java/yi/master/coretest/message/protocol/SocketTestClient.java @@ -5,6 +5,7 @@ import yi.master.business.testconfig.bean.TestConfig; import yi.master.constant.MessageKeys; import yi.master.coretest.message.process.LiaoNingSocketMsgProcess; import yi.master.coretest.message.protocol.entity.ClientTestResponseObject; +import yi.master.coretest.message.test.TestMessageScene; import yi.master.util.PracticalUtils; import java.io.*; @@ -29,8 +30,11 @@ public class SocketTestClient extends TestClient { } @Override - public ClientTestResponseObject sendRequest(String requestUrl, - String requestMessage, Map callParameter, TestConfig config, Object client) { + public ClientTestResponseObject sendRequest(TestMessageScene scene, Object client) { + String requestUrl = scene.getRequestUrl(); + String requestMessage = scene.getRequestMessage(); + Map callParameter = scene.getCallParameter(); + TestConfig config = scene.getConfig(); ClientTestResponseObject returnMap = new ClientTestResponseObject(); diff --git a/src/main/java/yi/master/coretest/message/protocol/TestClient.java b/src/main/java/yi/master/coretest/message/protocol/TestClient.java index b5edc21..ab35a88 100644 --- a/src/main/java/yi/master/coretest/message/protocol/TestClient.java +++ b/src/main/java/yi/master/coretest/message/protocol/TestClient.java @@ -1,13 +1,10 @@ package yi.master.coretest.message.protocol; import org.apache.log4j.Logger; -import yi.master.business.testconfig.bean.TestConfig; import yi.master.constant.MessageKeys; import yi.master.coretest.message.protocol.entity.ClientTestResponseObject; import yi.master.coretest.message.test.TestMessageScene; -import java.util.Map; - /** * * 测试客户端,不同协议的请求通过工厂方法获取 @@ -20,19 +17,14 @@ public abstract class TestClient { public static final Logger LOGGER = Logger.getLogger(TestClient.class.getName()); /** - * 发送测试请求到指定接口地址 - * @param requestUrl 请求地址 - * @param requestMessage 请求报文 - * @param callParameter 自定义的请求参数,不同类型报文格式,不同请求协议需要不同的配置规则 - * @param config 用户的测试配置,不会再这里面配置太多内容 - * @return 测试结果详情 - * + * 具体发送请求的方法,各协议不相同 + * @author xuwangcheng + * @date 2021/1/30 16:38 + * @param scene scene + * @param client client + * @return {@link ClientTestResponseObject} */ - public abstract ClientTestResponseObject sendRequest(String requestUrl, String requestMessage, Map callParameter, TestConfig config, Object client); - - public ClientTestResponseObject sendRequest(TestMessageScene scene, Object client) { - return sendRequest(scene.getRequestUrl(), scene.getRequestMessage(), scene.getCallParameter(), scene.getConfig(), client); - }; + public abstract ClientTestResponseObject sendRequest(TestMessageScene scene, Object client); /** * 测试该接口地址是否可通 diff --git a/src/main/java/yi/master/coretest/message/protocol/WebSocketTestClient.java b/src/main/java/yi/master/coretest/message/protocol/WebSocketTestClient.java index 8736abf..b0a2829 100644 --- a/src/main/java/yi/master/coretest/message/protocol/WebSocketTestClient.java +++ b/src/main/java/yi/master/coretest/message/protocol/WebSocketTestClient.java @@ -4,11 +4,11 @@ import cn.hutool.core.util.StrUtil; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.java_websocket.client.WebSocketClient; -import org.java_websocket.framing.CloseFrame; import org.java_websocket.handshake.ServerHandshake; import yi.master.business.testconfig.bean.TestConfig; import yi.master.constant.MessageKeys; import yi.master.coretest.message.protocol.entity.ClientTestResponseObject; +import yi.master.coretest.message.test.TestMessageScene; import yi.master.util.PracticalUtils; import java.net.URI; @@ -36,7 +36,12 @@ public class WebSocketTestClient extends TestClient { } @Override - public ClientTestResponseObject sendRequest(String requestUrl, String requestMessage, Map callParameter, TestConfig config, Object client) { + public ClientTestResponseObject sendRequest(TestMessageScene scene, Object client) { + String requestUrl = scene.getRequestUrl(); + String requestMessage = scene.getRequestMessage(); + Map callParameter = scene.getCallParameter(); + TestConfig config = scene.getConfig(); + int connectTimeOut = config.getConnectTimeOut(); int readTimeOut = config.getReadTimeOut(); if (callParameter != null) { diff --git a/src/main/java/yi/master/coretest/message/protocol/WebserviceTestClient.java b/src/main/java/yi/master/coretest/message/protocol/WebserviceTestClient.java index b4ea068..0c6ea93 100644 --- a/src/main/java/yi/master/coretest/message/protocol/WebserviceTestClient.java +++ b/src/main/java/yi/master/coretest/message/protocol/WebserviceTestClient.java @@ -3,9 +3,9 @@ package yi.master.coretest.message.protocol; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient; -import yi.master.business.testconfig.bean.TestConfig; import yi.master.constant.MessageKeys; import yi.master.coretest.message.protocol.entity.ClientTestResponseObject; +import yi.master.coretest.message.test.TestMessageScene; import yi.master.util.PracticalUtils; import javax.xml.namespace.QName; @@ -25,9 +25,11 @@ public class WebserviceTestClient extends TestClient { } @Override - public ClientTestResponseObject sendRequest(String requestUrl, - String requestMessage, Map callParameter, TestConfig config, Object client) { - + public ClientTestResponseObject sendRequest(TestMessageScene scene, Object client) { + String requestUrl = scene.getRequestUrl(); + String requestMessage = scene.getRequestMessage(); + Map callParameter = scene.getCallParameter(); + String username = null; String password = null; String namespace = ""; diff --git a/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java b/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java index f81d20a..ed15655 100644 --- a/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java +++ b/src/main/java/yi/master/coretest/message/test/MessageAutoTest.java @@ -200,6 +200,7 @@ public class MessageAutoTest { result.setResponseMessage(parseUtil.messageFormatBeautify(responseMessage)); result.setStatusCode(responseMap.getStatusCode()); + result.setProxyInfo(createProxyInfo(testScene.getBusinessSystem()).toString()); if (SystemConsts.DefaultBooleanIdentify.FALSE.getString().equals(result.getStatusCode()) || !PracticalUtils.isNormalString(result.getResponseMessage())) { @@ -920,4 +921,21 @@ public class MessageAutoTest { return results; } + private JSONObject createProxyInfo (BusinessSystem system) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("useProxy", "否"); + if (system != null && SystemConsts.DefaultBooleanIdentify.TRUE.getNumber().equals(system.getUseProxy())) { + if (StringUtils.isNotBlank(system.getProxyHost()) && system.getProxyPort() != null) { + jsonObject.put("useProxy", "是"); + jsonObject.put("proxyHost", system.getProxyHost()); + jsonObject.put("proxyPort", system.getProxyPort()); + jsonObject.put("proxyUsername", system.getProxyUsername()); + jsonObject.put("proxyPassword", system.getProxyPassword()); + + return jsonObject; + } + } + return jsonObject; + } + } diff --git a/src/main/java/yi/master/listener/VersionUpdateUtil.java b/src/main/java/yi/master/listener/VersionUpdateUtil.java index 78a8e3b..44a74c8 100644 --- a/src/main/java/yi/master/listener/VersionUpdateUtil.java +++ b/src/main/java/yi/master/listener/VersionUpdateUtil.java @@ -53,6 +53,7 @@ public class VersionUpdateUtil { ALL_VERSION_LIST.add("1.0.5"); ALL_VERSION_LIST.add("1.1.0"); ALL_VERSION_LIST.add("1.1.1"); + ALL_VERSION_LIST.add("1.1.2"); } /** diff --git a/src/main/resources/update/1.1.2 b/src/main/resources/update/1.1.2 new file mode 100644 index 0000000..b813893 --- /dev/null +++ b/src/main/resources/update/1.1.2 @@ -0,0 +1,8 @@ +SET FOREIGN_KEY_CHECKS=0; +ALTER TABLE `at_business_system` ADD COLUMN `use_proxy` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '0' COMMENT '是否使用代理' AFTER `mark`; +ALTER TABLE `at_business_system` ADD COLUMN `proxy_host` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '代理ip' AFTER `use_proxy`; +ALTER TABLE `at_business_system` ADD COLUMN `proxy_port` int(5) NULL DEFAULT NULL COMMENT '代理端口' AFTER `proxy_host`; +ALTER TABLE `at_business_system` ADD COLUMN `proxy_username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '代理认证用户名' AFTER `proxy_port`; +ALTER TABLE `at_business_system` ADD COLUMN `proxy_password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '代理认证密码' AFTER `proxy_username`; +ALTER TABLE `at_test_result` ADD COLUMN `proxy_info` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '代理服务器的信息' AFTER `business_system_name`; +SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file diff --git a/src/main/webapp/js/dcits.js b/src/main/webapp/js/dcits.js index 97d2c44..1ef3cc3 100644 --- a/src/main/webapp/js/dcits.js +++ b/src/main/webapp/js/dcits.js @@ -1999,7 +1999,18 @@ function renderResultViewPage(result, messageSceneId) { return; } layer_show('HTTP头信息', templates["scene-test-result-headers"](JSON.parse(result.headers)), 750, 440, 1); - }); + }); + layero.find("#view-proxy-info").click(function(){ + if (strIsNotEmpty(result.proxyInfo)) { + var proxyInfo = JSON.parse(result.proxyInfo) + if (proxyInfo.useProxy == "是") { + layer_show('代理信息', templates["scene-test-result-proxy"](proxyInfo), 380, 220, 1); + return; + } + } + layer.msg("没有使用代理", {icon:0, time:1500}); + return; + }); if (messageSceneId != null) { layero.find('tbody').prepend(''); layero.find('#save-response-example').click(function () { diff --git a/src/main/webapp/libs/jquery.validation/1.14.0/validate-methods.js b/src/main/webapp/libs/jquery.validation/1.14.0/validate-methods.js index 9406919..67baedb 100644 --- a/src/main/webapp/libs/jquery.validation/1.14.0/validate-methods.js +++ b/src/main/webapp/libs/jquery.validation/1.14.0/validate-methods.js @@ -116,6 +116,12 @@ $(function(){ return this.optional(element) || (tel.test(value)); }, "请正确填写您的电话号码。"); + // 电话号码验证 + jQuery.validator.addMethod("isIP", function(value, element) { + var ip = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/g; + return this.optional(element) || (ip.test(value)); + }, "请正确填写IP地址"); + // 联系电话(手机/电话皆可)验证 jQuery.validator.addMethod("isTel", function(value,element) { var length = value.length; diff --git a/src/main/webapp/resource/setting/businessSystem.js b/src/main/webapp/resource/setting/businessSystem.js index aef0cfc..9230518 100644 --- a/src/main/webapp/resource/setting/businessSystem.js +++ b/src/main/webapp/resource/setting/businessSystem.js @@ -1,5 +1,5 @@ var templateParams = { - tableTheads:["名称", "IP", "端口", "协议", "应用", "接口数量", "状态", "最后修改", "创建时间", "备注", "操作"], + tableTheads:["名称", "IP", "端口", "协议", "使用代理", "应用", "接口数量", "状态", "最后修改", "创建时间", "备注", "操作"], btnTools:[{ type:"primary", size:"M", @@ -66,6 +66,49 @@ var templateParams = { }() }] }, + { + edit:false, + required:true, + reminder: "目前代理功能仅支持HTTP/HTTPS", + label:"是否使用代理", + select:[{ + name:"useProxy", + option:[{value:"0", text:"否", selected:true}, + {value:"1", text:"是"}] + }] + }, + { + edit:false, + required:false, + label:"代理地址", + input:[{ + name:"proxyHost" + }] + }, + { + edit:false, + required:false, + label:"代理端口", + input:[{ + name:"proxyPort" + }] + }, + { + edit:false, + required:false, + label:"代理用户名", + input:[{ + name:"proxyUsername" + }] + }, + { + edit:false, + required:false, + label:"代理密码", + input:[{ + name:"proxyPassword" + }] + }, { label:"应用", input:[{ @@ -124,6 +167,21 @@ var columnsSetting = [{"data":null, "render":function(data) { return labelCreate(data.toUpperCase()); } + }, + { + "data":"useProxy", + "render":function(data) { + return labelCreate(data, { + "1":{ + btnStyle:"success", + status:"是" + }, + "0":{ + btnStyle:"default", + status:"否" + } + }); + } }, {"data":"softwareName"}, { @@ -231,14 +289,22 @@ var mySetting = { }, systemPort:{ required:true - } + }, + proxyPort:{ + digits:true, + min: 1, + max: 65535 + }, + // proxyHost:{ + // isIP:true + // } } }, listPage:{ listUrl:REQUEST_URL.BUSINESS_SYSTEM.LIST_ALL, tableObj:".table-sort", columnsSetting:columnsSetting, - columnsJson:[0, 11, 12], + columnsJson:[0, 12, 13], dtOtherSetting:{serverSide:false} }, templateParams:templateParams diff --git a/src/main/webapp/resource/template/customTemplate.htm b/src/main/webapp/resource/template/customTemplate.htm index c78316b..12878dd 100644 --- a/src/main/webapp/resource/template/customTemplate.htm +++ b/src/main/webapp/resource/template/customTemplate.htm @@ -380,6 +380,10 @@ 头信息: + + 代理信息: + + 状态码: {{statusCode}} @@ -421,7 +425,7 @@ {{#each RequestHeader}} - {{@key}} + {{@key}} {{this}} {{/each}} @@ -430,12 +434,32 @@ {{#each ResponseHeader}} - {{@key}} + {{@key}} {{this}} {{/each}} +