|
|
@@ -0,0 +1,350 @@
|
|
|
+package seecoder.devcloud.web.service.impl.APITest;
|
|
|
+
|
|
|
+import com.google.gson.Gson;
|
|
|
+import net.sf.json.JSONArray;
|
|
|
+import net.sf.json.JSONObject;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import seecoder.devcloud.web.dao.APITest.APITestMapper;
|
|
|
+import seecoder.devcloud.web.model.po.APITest.APITestInfo;
|
|
|
+import seecoder.devcloud.web.model.po.APITest.APITest;
|
|
|
+import seecoder.devcloud.web.model.vo.APITest.APITestBodyVO;
|
|
|
+import seecoder.devcloud.web.model.vo.APITest.APITestInfoVO;
|
|
|
+import seecoder.devcloud.web.service.APITest.APITestService;
|
|
|
+
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.io.OutputStreamWriter;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.URL;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.CountDownLatch;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class APITestServiceImpl implements APITestService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private APITestMapper apiTestMapper;
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void createAPITest(APITestBodyVO apiTestBodyVO) {
|
|
|
+ APITest apiTest = APITest.builder()
|
|
|
+ .testName(apiTestBodyVO.getTestName())
|
|
|
+ .projectId(apiTestBodyVO.getProjectId())
|
|
|
+ .createTime(apiTestBodyVO.getCreateTime())
|
|
|
+ .username(apiTestBodyVO.getUsername())
|
|
|
+ .url(apiTestBodyVO.getUrl())
|
|
|
+ .params(JSONObject.fromObject(apiTestBodyVO.getParams()).toString())
|
|
|
+ .method(apiTestBodyVO.getMethod())
|
|
|
+ .qps(apiTestBodyVO.getQps())
|
|
|
+ .state("进行中")
|
|
|
+ .success(0)
|
|
|
+ .failure(0)
|
|
|
+ .timeList("")
|
|
|
+ .build();
|
|
|
+ apiTestMapper.insert(apiTest);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void deleteAPITest(Integer projectId) {
|
|
|
+ apiTestMapper.delete(projectId);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<APITestInfoVO> getAPITestsByProjectId(Integer projectId) {
|
|
|
+ List<APITest> apiTestInfoVOs = apiTestMapper.selectByProjectId(projectId);
|
|
|
+ List<APITestInfoVO> apiTestInfoVOList = new ArrayList<>();
|
|
|
+ for (APITest apiTest : apiTestInfoVOs) {
|
|
|
+ apiTestInfoVOList.add(new APITestInfoVO(transform(apiTest)));
|
|
|
+ }
|
|
|
+ return apiTestInfoVOList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void executeAPITest(Integer testId) throws InterruptedException {
|
|
|
+ APITest apiTest = apiTestMapper.selectByTestId(testId);
|
|
|
+ String url = apiTest.getUrl();
|
|
|
+ Map<String, Object> params = parseJson2Map(apiTest.getParams());
|
|
|
+ int qps = apiTest.getQps();
|
|
|
+ String method = apiTest.getMethod();
|
|
|
+
|
|
|
+ System.out.println(method);
|
|
|
+ if (method.equals("GET")) { // GET方法
|
|
|
+ handleRequest(url, params, qps, testId, "GET");
|
|
|
+ } else if (method.equals("POST")) { // POST方法
|
|
|
+ handleRequest(url, params, qps, testId, "POST");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将数据库中读取的 APITestInfoMysql 转为 APITestInfo
|
|
|
+ public APITestInfo transform(APITest apiTest) {
|
|
|
+ APITestInfo apiTestInfo = new APITestInfo();
|
|
|
+ apiTestInfo.setTestId(apiTest.getTestId());
|
|
|
+ apiTestInfo.setTestName(apiTest.getTestName());
|
|
|
+ apiTestInfo.setProjectId(apiTest.getProjectId());
|
|
|
+ apiTestInfo.setCreateTime(apiTest.getCreateTime());
|
|
|
+ apiTestInfo.setUsername(apiTest.getUsername());
|
|
|
+ apiTestInfo.setUrl(apiTest.getUrl());
|
|
|
+ apiTestInfo.setParams(parseJson2Map(apiTest.getParams()));
|
|
|
+ apiTestInfo.setMethod(apiTest.getMethod());
|
|
|
+ apiTestInfo.setQps(apiTest.getQps());
|
|
|
+ apiTestInfo.setState(apiTest.getState());
|
|
|
+ apiTestInfo.setExecuteTime(apiTest.getExecuteTime());
|
|
|
+ apiTestInfo.setSuccess(apiTest.getSuccess());
|
|
|
+ apiTestInfo.setFailure(apiTest.getFailure());
|
|
|
+ apiTestInfo.setTimeList(splitTimeList(apiTest.getTimeList()));
|
|
|
+ return apiTestInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将JSON格式的字符串转为 Map类型
|
|
|
+ public Map<String, Object> parseJson2Map(String str) {
|
|
|
+ Map<String, Object> map = new HashMap<String, Object>();
|
|
|
+ JSONObject json = JSONObject.fromObject(str);
|
|
|
+ for (Object k:json.keySet()) {
|
|
|
+ Object v = json.get(k);
|
|
|
+ if (v instanceof JSONArray) {
|
|
|
+ List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
|
|
|
+ Iterator<JSONObject> it = ((JSONArray)v).iterator();
|
|
|
+ while (it.hasNext()) {
|
|
|
+ JSONObject json2 = it.next();
|
|
|
+ list.add(parseJson2Map(json2.toString()));
|
|
|
+ }
|
|
|
+ map.put(k.toString(), list);
|
|
|
+ } else {
|
|
|
+ map.put(k.toString(), v);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分隔字符串
|
|
|
+ public List<Integer> splitTimeList(String time) {
|
|
|
+ List<Integer> timeList = new ArrayList<Integer>();
|
|
|
+ if (time.length() == 0) {
|
|
|
+ return timeList;
|
|
|
+ }
|
|
|
+ String[] tl = time.split(",");
|
|
|
+ for (String t:tl) {
|
|
|
+ timeList.add(Integer.parseInt(t));
|
|
|
+ }
|
|
|
+ return timeList;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理请求
|
|
|
+ public void handleRequest(String url, Map<String, Object> params, int qps, int testId, String method) throws InterruptedException {
|
|
|
+ ArrayList<Integer> timeList = new ArrayList<>();
|
|
|
+ final int[] success = {0};
|
|
|
+ final int[] failure = {0};
|
|
|
+ Runnable task = new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ for (int i = 0; i < qps / 10; i++) {
|
|
|
+ int[] arr = new int[2];
|
|
|
+ if (method.equals("GET")) {
|
|
|
+ arr = doGet(url, params);
|
|
|
+ } else if (method.equals("POST")) {
|
|
|
+ try {
|
|
|
+ arr = doPost(url, params);
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ timeList.add(arr[1]);
|
|
|
+ if (arr[0] == 1) success[0]++;
|
|
|
+ else failure[0]++;
|
|
|
+ try{
|
|
|
+ Thread.sleep(100);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ APITestServiceImpl apiTestService = new APITestServiceImpl();
|
|
|
+ apiTestService.startTaskAllInOnce(10, task);
|
|
|
+ String tl = "";
|
|
|
+ for (int j = 0; j < timeList.size(); j++) {
|
|
|
+ if (j != timeList.size() - 1) tl += timeList.get(j).toString() + ",";
|
|
|
+ else tl += timeList.get(j).toString();
|
|
|
+ }
|
|
|
+ Date d = new Date();
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ String executeTime = sdf.format(d);
|
|
|
+ System.out.println(success[0]);
|
|
|
+ apiTestMapper.update("完成", executeTime, success[0], failure[0], tl, testId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理GET请求
|
|
|
+ public int[] doGet(String url, Map<String, Object> params) {
|
|
|
+ HttpURLConnection connection = null;
|
|
|
+ BufferedReader br = null;
|
|
|
+ StringBuffer sb = new StringBuffer();
|
|
|
+ String result = "";
|
|
|
+ String path = "";
|
|
|
+ int[] arr = new int[2];
|
|
|
+ int flag = 0;
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ try {
|
|
|
+ if (params.size() == 1) {
|
|
|
+ for (String name:params.keySet()) {
|
|
|
+ sb.append(name).append("=").append(URLEncoder.encode((String) params.get(name), "UTF-8"));
|
|
|
+ }
|
|
|
+ path = sb.toString();
|
|
|
+ } else if (params.size() >= 2) {
|
|
|
+ for (String name:params.keySet()) {
|
|
|
+ sb.append(name).append("=").append(URLEncoder.encode((String) params.get(name), "UTF-8")).append("&");
|
|
|
+ }
|
|
|
+ String temp_path = sb.toString();
|
|
|
+ path = temp_path.substring(0, temp_path.length() - 1);
|
|
|
+ }
|
|
|
+ String full_url = "";
|
|
|
+ if (path != "") {
|
|
|
+ full_url = url + "?" + path;
|
|
|
+ } else {
|
|
|
+ full_url = url;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (full_url.startsWith("localhost")) {
|
|
|
+ full_url = "http://" + full_url;
|
|
|
+ }
|
|
|
+ URL connURL = new URL(full_url);
|
|
|
+
|
|
|
+ connection = (HttpURLConnection) connURL.openConnection();
|
|
|
+ // 设置一些属性
|
|
|
+ connection.setRequestProperty("Accept", "*/*");
|
|
|
+ connection.setRequestProperty("Connection", "Keep-Alive");
|
|
|
+ connection.setRequestProperty("User-Agent",
|
|
|
+ "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
|
|
|
+ connection.setConnectTimeout(15000);
|
|
|
+ connection.setReadTimeout(60000);
|
|
|
+
|
|
|
+ // 建立连接
|
|
|
+ connection.connect();
|
|
|
+ if (connection.getResponseCode() == 200) {
|
|
|
+ flag = 1;
|
|
|
+ } else {
|
|
|
+ flag = 0;
|
|
|
+ }
|
|
|
+ br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
|
|
|
+ String line;
|
|
|
+ while ((line = br.readLine()) != null) {
|
|
|
+ result += line;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ try {
|
|
|
+ if (br != null)
|
|
|
+ br.close();
|
|
|
+ } catch (IOException ex) {
|
|
|
+ ex.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+// System.out.println(result);
|
|
|
+ int time = Long.valueOf(end - start).intValue();
|
|
|
+ arr[0] = flag;
|
|
|
+ arr[1] = time;
|
|
|
+ return arr;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理POST请求
|
|
|
+ public int[] doPost(String url, Map<String, Object> params) throws IOException{
|
|
|
+ Gson gson = new Gson();
|
|
|
+ String param = gson.toJson(params);
|
|
|
+ OutputStreamWriter out = null;
|
|
|
+ BufferedReader reader = null;
|
|
|
+ String response = "";
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ int[] arr = new int[2];
|
|
|
+ int flag = 0;
|
|
|
+ try {
|
|
|
+ URL httpUrl = null;
|
|
|
+ httpUrl = new URL(url);
|
|
|
+ HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
|
|
|
+ conn.setRequestMethod("POST");
|
|
|
+ conn.setRequestProperty("Content-Type", "application/json");
|
|
|
+ conn.setRequestProperty("connection", "keep-alive");
|
|
|
+ conn.setUseCaches(false);//设置不要缓存
|
|
|
+ conn.setInstanceFollowRedirects(true);
|
|
|
+ conn.setDoOutput(true);
|
|
|
+ conn.setDoInput(true);
|
|
|
+ conn.connect();
|
|
|
+ // POST请求
|
|
|
+ out = new OutputStreamWriter(conn.getOutputStream());
|
|
|
+ out.write(param);
|
|
|
+ out.flush();
|
|
|
+ if (conn.getResponseCode() == 200) {
|
|
|
+ flag = 1;
|
|
|
+ } else {
|
|
|
+ flag = 0;
|
|
|
+ }
|
|
|
+ // 读取响应
|
|
|
+ reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
|
|
+ String lines;
|
|
|
+ while ((lines = reader.readLine()) != null) {
|
|
|
+ lines = new String(lines.getBytes(), "utf-8");
|
|
|
+ response += lines;
|
|
|
+ }
|
|
|
+ reader.close();
|
|
|
+ // 断开连接
|
|
|
+ conn.disconnect();
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("发送 POST 请求出现异常!"+e);
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally{
|
|
|
+ try{
|
|
|
+ if(out!=null){
|
|
|
+ out.close();
|
|
|
+ }
|
|
|
+ if(reader!=null){
|
|
|
+ reader.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch(IOException ex){
|
|
|
+ ex.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+ int time = Long.valueOf(end - start).intValue();
|
|
|
+ arr[0] = flag;
|
|
|
+ arr[1] = time;
|
|
|
+ return arr;
|
|
|
+ }
|
|
|
+
|
|
|
+ public long startTaskAllInOnce(int threadNums, final Runnable task) throws InterruptedException {
|
|
|
+ final CountDownLatch startGate = new CountDownLatch(1);
|
|
|
+ final CountDownLatch endGate = new CountDownLatch(threadNums);
|
|
|
+ for (int i = 0; i < threadNums; i++) {
|
|
|
+ Thread t = new Thread() {
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ startGate.await();
|
|
|
+ try {
|
|
|
+ task.run();
|
|
|
+ } finally {
|
|
|
+ endGate.countDown();
|
|
|
+ }
|
|
|
+ } catch (InterruptedException ie) {
|
|
|
+ ie.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ t.start();
|
|
|
+ }
|
|
|
+ long startTime = System.nanoTime();
|
|
|
+ System.out.println(startTime + " [" + Thread.currentThread() + "] All thread is ready, concurrent going...");
|
|
|
+ // 因开启门只需一个开关,所以立马就开启开始门
|
|
|
+ startGate.countDown();
|
|
|
+ // 等等结束门开启
|
|
|
+ endGate.await();
|
|
|
+ long endTime = System.nanoTime();
|
|
|
+ System.out.println(endTime + " [" + Thread.currentThread() + "] All thread is completed.");
|
|
|
+ return endTime - startTime;
|
|
|
+ }
|
|
|
+}
|