Quellcode durchsuchen

Merge branch 'zxr'

370774330@qq.com vor 5 Jahren
Ursprung
Commit
5c61531dc5

+ 60 - 0
web/src/main/java/seecoder/devcloud/web/controller/APITest/APITestController.java

@@ -0,0 +1,60 @@
+package seecoder.devcloud.web.controller.APITest;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import seecoder.devcloud.web.model.vo.APITest.APITestBodyVO;
+import seecoder.devcloud.web.model.vo.APITest.APITestInfoVO;
+import seecoder.devcloud.web.model.vo.Response;
+import seecoder.devcloud.web.service.APITest.APITestService;
+
+import java.util.List;
+
+/**
+ * @Author zxr
+ * @Description 接口测试相关操作
+ */
+@Api(tags = "接口测试 API")
+@RestController
+@RequestMapping("/apitest")
+public class APITestController {
+
+    private final APITestService apiTestService;
+
+    @Autowired
+    public APITestController(APITestService apiTestService) {
+        this.apiTestService = apiTestService;
+    }
+
+    @PostMapping("/create")
+    @ApiOperation(value = "创建一个新的测试任务", httpMethod = "POST")
+    public Response createAPITestMission(@RequestBody APITestBodyVO apiTestBodyVO) {
+        apiTestService.createAPITest(apiTestBodyVO);
+        return Response.buildSuccess();
+    }
+
+    @GetMapping("/list/{projectId}")
+    @ApiOperation(value = "获取指定项目的所有测试任务", httpMethod = "GET")
+    @ApiImplicitParam(name = "projectId", dataType ="int",paramType = "query")
+    public Response<List<APITestInfoVO>> getAPITestInfosByProjectId(@PathVariable("projectId") Integer projectId) {
+        return Response.buildSuccess(apiTestService.getAPITestsByProjectId(projectId));
+    }
+
+    @GetMapping("/delete/{testId}")
+    @ApiOperation(value = "删除指定测试任务", httpMethod = "DELETE")
+    @ApiImplicitParam(name = "testId", dataType = "int", paramType = "query")
+    public Response deleteAPITestInfoByTestId(@PathVariable("testId") Integer testId) {
+        apiTestService.deleteAPITest(testId);
+        return Response.buildSuccess();
+    }
+
+    @GetMapping("/execute/{testId}")
+    @ApiOperation(value = "执行制定测试任务", httpMethod = "GET")
+    @ApiImplicitParam(name = "testID", dataType = "int", paramType = "query")
+    public Response executeAPITestByTestId(@PathVariable("testId") Integer testId) throws InterruptedException {
+        apiTestService.executeAPITest(testId);
+        return Response.buildSuccess();
+    }
+}

+ 32 - 0
web/src/main/java/seecoder/devcloud/web/dao/APITest/APITestMapper.java

@@ -0,0 +1,32 @@
+package seecoder.devcloud.web.dao.APITest;
+
+import org.apache.ibatis.annotations.*;
+import seecoder.devcloud.web.dao.provider.GeneralInsertUpdateSqlProvider;
+import seecoder.devcloud.web.model.po.APITest.APITest;
+
+import java.util.List;
+
+/**
+ * @author zhaoxingrui
+ * @date 2021/3/20
+ * @description:
+ */
+@Mapper
+public interface APITestMapper {
+
+    @InsertProvider(type = GeneralInsertUpdateSqlProvider.class, method = "insert")
+    @Options(useGeneratedKeys = true, keyProperty = "param1.testId")
+    boolean insert(APITest apiTest, String... ignoredCols);
+
+    @Select("select * from api_test where project_id = #{id}")
+    List<APITest> selectByProjectId(Integer id);
+
+    @Select("select * from api_test where test_id = #{id}")
+    APITest selectByTestId(Integer id);
+
+    @Delete("delete from api_test where test_id = #{id}")
+    boolean delete(Integer id);
+
+    @Update("update api_test set state = #{state}, execute_time = #{executeTime}, success = #{success}, failure = #{failure}, time_list = #{timeList} where test_id = #{id}")
+    boolean update(@Param("state") String state, @Param("executeTime") String executeTime, @Param("success") Integer success, @Param("failure") Integer failure, @Param("timeList") String timeList, @Param("id") Integer id);
+}

+ 1 - 0
web/src/main/java/seecoder/devcloud/web/dao/pipeline/PipelineMapper.java

@@ -19,6 +19,7 @@ public interface PipelineMapper {
     @Options(useGeneratedKeys = true, keyProperty = "param1.id", keyColumn = "id")
     boolean insert(PipelinePO pipelinePO, String... ignoredCols);
 
+
     @Select("select * from pipeline where id = #{id}")
     PipelinePO selectById(Integer id);
 

+ 37 - 0
web/src/main/java/seecoder/devcloud/web/model/po/APITest/APITest.java

@@ -0,0 +1,37 @@
+package seecoder.devcloud.web.model.po.APITest;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author zhaoxingrui
+ * @date 2021/3/20
+ * @description:
+ */
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class APITest {
+    private Integer testId;
+    private String testName;
+    private Integer projectId;
+    private String createTime;
+    private String username;
+    private String url;
+    private String params;
+    private String method;
+    private Integer qps;
+    private String state;
+    private String executeTime;
+    private Integer success;
+    private Integer failure;
+    private String timeList;
+}

+ 27 - 0
web/src/main/java/seecoder/devcloud/web/model/po/APITest/APITestBody.java

@@ -0,0 +1,27 @@
+package seecoder.devcloud.web.model.po.APITest;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.sql.Timestamp;
+import java.util.Map;
+
+/**
+ * @author XingRui Zhao
+ * @date 2021/3/17
+ * @description:
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class APITestBody {
+    private Integer projectId;
+    private String createTime;
+    private String username;
+    private String testName;
+    private String url;
+    private Map<String, Object> params;
+    private String method;
+    private Integer qps;
+}

+ 36 - 0
web/src/main/java/seecoder/devcloud/web/model/po/APITest/APITestInfo.java

@@ -0,0 +1,36 @@
+package seecoder.devcloud.web.model.po.APITest;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author zhaoxingrui
+ * @date 2021/3/17
+ * @description:
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class APITestInfo {
+    private Integer testId;
+    private String testName;
+    private Integer projectId;
+    private String createTime;
+    private String username;
+    private String url;
+    private Map<String, Object> params;
+    private String method;
+    private Integer qps;
+    private String state;
+    private String executeTime;
+    private Integer success;
+    private Integer failure;
+    private List<Integer> timeList;
+}

+ 52 - 0
web/src/main/java/seecoder/devcloud/web/model/vo/APITest/APITestBodyVO.java

@@ -0,0 +1,52 @@
+package seecoder.devcloud.web.model.vo.APITest;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import seecoder.devcloud.web.model.po.APITest.APITestBody;
+
+import java.sql.Timestamp;
+import java.util.Map;
+
+/**
+ * @author zhaoxingrui
+ * @date 2021/3/17
+ * @description:
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel("新建测试任务@")
+public class APITestBodyVO {
+
+    @ApiModelProperty("测试任务所属的project Id")
+    private Integer projectId;
+
+    @ApiModelProperty("测试名称")
+    private String testName;
+
+    @ApiModelProperty("测试创建时间")
+    private String createTime;
+
+    @ApiModelProperty("测试创建者")
+    private String username;
+
+    @ApiModelProperty("测试url")
+    private String url;
+
+    @ApiModelProperty("测试url中可能携带的参数")
+    private Map<String, Object> params;
+
+    @ApiModelProperty("测试url的方法get/post")
+    private String method;
+
+    @ApiModelProperty("测试并发数")
+    private Integer qps;
+
+    public APITestBodyVO(APITestBody apiTestBody) {
+        BeanUtils.copyProperties(apiTestBody, this);
+    }
+}

+ 71 - 0
web/src/main/java/seecoder/devcloud/web/model/vo/APITest/APITestInfoVO.java

@@ -0,0 +1,71 @@
+package seecoder.devcloud.web.model.vo.APITest;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import seecoder.devcloud.web.model.po.APITest.APITestInfo;
+
+import java.sql.Timestamp;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author zhaoxingrui
+ * @date 2021/3/17
+ * @description:
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel("测试任务的详细信息")
+public class APITestInfoVO {
+
+    @ApiModelProperty("测试id")
+    private Integer testId;
+
+    @ApiModelProperty("测试名称")
+    private String testName;
+
+    @ApiModelProperty("测试所属项目")
+    private Integer projectId;
+
+    @ApiModelProperty("创建时间")
+    private String createTime;
+
+    @ApiModelProperty("创建者")
+    private String username;
+
+    @ApiModelProperty("测试url")
+    private String url;
+
+    @ApiModelProperty("测试可能携带的参数")
+    private Map<String, Object> params;
+
+    @ApiModelProperty("测试url的方法get/post")
+    private String method;
+
+    @ApiModelProperty("测试并发数")
+    private Integer qps;
+
+    @ApiModelProperty("测试任务状态")
+    private String state;
+
+    @ApiModelProperty("测试执行时间")
+    private String executeTime;
+
+    @ApiModelProperty("测试成功次数")
+    private Integer success;
+
+    @ApiModelProperty("测试失败次数")
+    private Integer failure;
+
+    @ApiModelProperty("测试结果list")
+    private List<Integer> timeList;
+
+    public APITestInfoVO(APITestInfo apiTestInfo) {
+        BeanUtils.copyProperties(apiTestInfo, this);
+    }
+}

+ 68 - 0
web/src/main/java/seecoder/devcloud/web/model/vo/APITest/APITestVO.java

@@ -0,0 +1,68 @@
+package seecoder.devcloud.web.model.vo.APITest;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.BeanUtils;
+import seecoder.devcloud.web.model.po.APITest.APITest;
+
+import java.sql.Timestamp;
+
+/**
+ * @author zhaoxingrui
+ * @date: 2021/3/20
+ * @description:
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor@ApiModel("测试任务在mysql数据库中的类型")
+public class APITestVO {
+    @ApiModelProperty("测试id")
+    private Integer testId;
+
+    @ApiModelProperty("测试名称")
+    private String testName;
+
+    @ApiModelProperty("测试所属项目")
+    private Integer projectId;
+
+    @ApiModelProperty("创建时间")
+    private String createTime;
+
+    @ApiModelProperty("创建者")
+    private String username;
+
+    @ApiModelProperty("测试url")
+    private String url;
+
+    @ApiModelProperty("测试可能携带的参数")
+    private String params;
+
+    @ApiModelProperty("测试url的方法get/post")
+    private String method;
+
+    @ApiModelProperty("测试并发数")
+    private Integer qps;
+
+    @ApiModelProperty("测试任务状态")
+    private String state;
+
+    @ApiModelProperty("测试执行时间")
+    private String executeTime;
+
+    @ApiModelProperty("测试成功次数")
+    private Integer success;
+
+    @ApiModelProperty("测试失败次数")
+    private Integer failure;
+
+    @ApiModelProperty("测试结果list")
+    private String timeList;
+
+    public APITestVO(APITest apiTest) {
+        BeanUtils.copyProperties(apiTest, this);
+    }
+
+}

+ 33 - 0
web/src/main/java/seecoder/devcloud/web/service/APITest/APITestService.java

@@ -0,0 +1,33 @@
+package seecoder.devcloud.web.service.APITest;
+
+import seecoder.devcloud.web.model.vo.APITest.APITestBodyVO;
+import seecoder.devcloud.web.model.vo.APITest.APITestInfoVO;
+
+import java.util.List;
+
+/**
+ * @author zhaoxingrui
+ * @date 2021/3/19
+ * @description: 接口测试相关的service
+ */
+public interface APITestService {
+    /**
+     * 新建一个接口测试任务
+     */
+    void createAPITest(APITestBodyVO apiTestBodyVO);
+
+    /**
+     * 获取指定项目的所有测试任务
+     */
+    List<APITestInfoVO> getAPITestsByProjectId(Integer projectId);
+
+    /**
+     * 删除指定测试任务
+     */
+    void deleteAPITest(Integer projectId);
+
+    /**
+     * 执行指定测试任务
+     */
+    void executeAPITest(Integer testId) throws InterruptedException;
+}

+ 350 - 0
web/src/main/java/seecoder/devcloud/web/service/impl/APITest/APITestServiceImpl.java

@@ -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;
+    }
+}

+ 0 - 0
web/src/main/resources/SQLScripts/apiTest.sql


+ 59 - 0
web/src/main/resources/application-zxr.yml

@@ -0,0 +1,59 @@
+spring:
+  datasource:
+    url: jdbc:mysql://localhost:3306/devcloud?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
+    username: root
+    password: zhaoXR429314
+
+  mail:
+    host: smtp.qq.com
+    username: 370774330@qq.com
+    password: qkoecnzivukvbibi
+    port: 465
+    protocol: smtp
+    properties:
+      mail:
+        smtp:
+          ssl:
+            enable: true
+          socketFactory.class: javax.net.ssl.SSLSocketFactory
+        debug: true
+server:
+  port: 8080
+
+mybatis:
+  configuration:
+    map-underscore-to-camel-case: true
+
+seecoder:
+  jwt:
+    secret: U0VFQy0xOTE5ODEwLU9JREMtMTE0NTE0
+  k8s:
+    api-server: https://192.168.99.105:8443
+    token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjBmSXc4RlRjNUpBYVpGYWc4QzRDY1MzUWJad1JMdFhKcDI1cngzWGtiRlkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZXZjbG91ZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXNicXY4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5NmIxNzU1ZS0zZjE3LTQ1ZTctODFmYi01MTRhODA3NDRhMzQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGV2Y2xvdWQ6ZGVmYXVsdCJ9.W0Y1lR6LBi1ZjylBx35YeqYuq2u2AqH-ayK4FD-LDfC26E89DanOwSv9XLrRMnnDBZFS_ZCRBumbnDeMiS5vw2x7-QnrDqj1M5u9FB2fIJsz2LyUkOhATZZmTzj_Uhewvvg09aDKh16ttj6ZX27m-KVk_6MP-VfiuvZnCVxDbqRkRjK-zsor4ty1CEATPyKK-tvugAwS0RFNHUL94DamfZAq_t1PSnH5ZtEHq0uEMZxY2c7j6u9d_aD9lphm_ZpCy_C8OCHfanM21CQPDHlcJTW_aiOO6bAp8qdc1egPO5uIamHl6Zm0N3RkcsRp4DGOHrltTV9y_cGZHXSWmRHfxw
+    debugging: true
+  gitlab:
+    host: http://gitlab.192.168.99.105.nip.io
+    webHookProxy: http://localhost:3000
+    token: wXDeETv2Kmt-JhiApJ9H
+  mail:
+    from: 370774330@qq.com
+  git:
+    password: mock
+    username: mock
+
+  jenkins:
+    host: http://192.168.68.79:8082
+    username: root
+    token: 11d7b9e4c1acac481904c25813e2ec1f0a
+  docker:
+    registry: 192.168.68.79:18082
+
+
+
+  registry:
+    host: 192.168.68.79:18082
+    username: admin
+    password: admin123
+    nexus-server: 192.168.68.79:18081
+    repo-name: sec-repo
+    clean-up-task: 83bb8249-71e8-4367-83b3-50c6f7518860