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 51e3b81b21edc4bd631abccd0c5fd319532f6b35..2ed74620d9e5e351c84214050c92f78839be58b6 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 78cebdf46c2d5a5bda43eca1d0e4c5264fbaceb5..670feb86a4d41d7b736eaa6daf236febf14e3b2a 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 1aff0fc484325382519e5dd4d052db3740151057..5659c549ac2f72c150740bb396558e81614fae9b 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 d944783c9b076a2f96462f87b43378681e4b06f2..ff59c5f65f0a9431ea874d06349337543a2576fb 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/MessageKeys.java b/src/main/java/yi/master/constant/MessageKeys.java index 954da02fba6911a8a0a37cc1c4b6149adc4ae589..45bc09440cb024345dcc81baa01773fb063df28f 100644 --- a/src/main/java/yi/master/constant/MessageKeys.java +++ b/src/main/java/yi/master/constant/MessageKeys.java @@ -302,6 +302,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/constant/SystemConsts.java b/src/main/java/yi/master/constant/SystemConsts.java index f03cf2441ccc959f87a4642ecde0c818ef0e46b3..efb30afb9695cc2022f0d2ed0a39a17060c7ce54 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 8c8093dd37d7f7364f6f779c82d8d1372e72baf5..ecce908823d380f761ac45c156f2925e64703733 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 a40eda45cfcd288710fa780696dc84e04241a02a..d5304988d40d0f95f90a093fc47b85c1b4a84269 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()); + 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 3c38cd4d575b01f3e71dc3f4c1cd350cbe9ba583..1b5a7e6b6383d98fafb41256b6cedd8aae7f49fd 100644 --- a/src/main/java/yi/master/coretest/message/protocol/SocketTestClient.java +++ b/src/main/java/yi/master/coretest/message/protocol/SocketTestClient.java @@ -4,6 +4,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.*; @@ -28,8 +29,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 b5edc21b5ed290cf88af54b3f53c36493d546e13..ab35a882fa8c3d9e2dafa5d21f50d7b4e47410a1 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 8736abfb419dd5721adc984561fd2d89cd1e463d..b0a282988a34bcaf0382cdd706fb0fb6f84dea64 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 b4ea0689f5fd877d2e4263452d3e9b7279b5ee92..0c6ea93dcce7af1be29c35b9e875f877b87f8df1 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 e66a5f96c4a8fec95070da7e95f52629ace4069c..ed15655956e1a23a8fa975af3e697031445f6273 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; @@ -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())) { @@ -426,16 +427,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 +450,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 +817,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); @@ -907,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 78a8e3b074d935fb4b8ff5ee75ff0b72b3f996e0..44a74c8b7e84d8f7cc34f177438a7f1d64717cc9 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/java/yi/master/util/PracticalUtils.java b/src/main/java/yi/master/util/PracticalUtils.java index 8c6afd90de52adc5e9027a88496da59080001c37..02f75acb82f6df6c5fe5ad9d5c6df793f257fd98 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/resources/update/1.1.2 b/src/main/resources/update/1.1.2 new file mode 100644 index 0000000000000000000000000000000000000000..b813893c1dbb992bcb99208fb1fde2f375eacea8 --- /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 97d2c44bb9b40516f0a2d50b6ea6d049cf2c7b54..1ef3cc3394e4d43165befe91b37b49c7f380bea5 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 940691971f1059644b810738b0bf65785d0c22f6..67baedb8d175639f77488abb11a2dfc8c551701b 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/message/messageScene.js b/src/main/webapp/resource/message/messageScene.js index 9dd273f38e6e0cd1b085e293dc12a5b53c62b164..b3d348720a689208153178d5d853c72553e5dd5b 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/src/main/webapp/resource/setting/businessSystem.js b/src/main/webapp/resource/setting/businessSystem.js index aef0cfc269c28e605d59e4f35f098c76cac1b214..9230518137f9632ab3275022042f80b641f20408 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 c78316bbef985579fd8c8be3531ed3863f5ffdaa..12878dd0f56823faa2da8380819998abdf615801 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}} +