Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
H
holmes
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
QA
holmes
Commits
aa5d6cc8
Commit
aa5d6cc8
authored
Jun 22, 2021
by
黎博
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into ldap
parents
f3d3077d
d0804b88
Changes
33
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
1372 additions
and
333 deletions
+1372
-333
pom.xml
pom.xml
+12
-0
InterfaceController.java
...ava/cn/qg/holmes/controller/auto/InterfaceController.java
+90
-0
SceneTestcaseController.java
...cn/qg/holmes/controller/auto/SceneTestcaseController.java
+25
-11
TestcaseController.java
...java/cn/qg/holmes/controller/auto/TestcaseController.java
+13
-1
GitlabController.java
...java/cn/qg/holmes/controller/gitlab/GitlabController.java
+63
-0
JenkinsController.java
...ava/cn/qg/holmes/controller/gitlab/JenkinsController.java
+40
-0
PipelineController.java
...va/cn/qg/holmes/controller/gitlab/PipelineController.java
+192
-0
JiraController.java
...ain/java/cn/qg/holmes/controller/jira/JiraController.java
+155
-42
JiraWebhookController.java
...a/cn/qg/holmes/controller/jira/JiraWebhookController.java
+0
-138
Scene.java
src/main/java/cn/qg/holmes/entity/auto/Scene.java
+1
-0
SceneTestcase.java
src/main/java/cn/qg/holmes/entity/auto/SceneTestcase.java
+3
-0
SceneTestcaseReport.java
...in/java/cn/qg/holmes/entity/auto/SceneTestcaseReport.java
+1
-0
SceneTestcaseUpdateVo.java
.../java/cn/qg/holmes/entity/auto/SceneTestcaseUpdateVo.java
+1
-0
Testcase.java
src/main/java/cn/qg/holmes/entity/auto/Testcase.java
+2
-0
DingRobotPipelineVo.java
.../java/cn/qg/holmes/entity/gitlab/DingRobotPipelineVo.java
+15
-0
Pipeline.java
src/main/java/cn/qg/holmes/entity/gitlab/Pipeline.java
+24
-0
DingRobot.java
src/main/java/cn/qg/holmes/entity/jira/DingRobot.java
+1
-0
SendSmokingResultVo.java
...in/java/cn/qg/holmes/entity/jira/SendSmokingResultVo.java
+13
-0
PipelineMapper.java
src/main/java/cn/qg/holmes/mapper/gitlab/PipelineMapper.java
+7
-0
AutoUtilsService.java
...main/java/cn/qg/holmes/service/auto/AutoUtilsService.java
+5
-3
AutoUtilsServiceImpl.java
.../cn/qg/holmes/service/auto/impl/AutoUtilsServiceImpl.java
+122
-37
SceneTestcaseServiceImpl.java
...qg/holmes/service/auto/impl/SceneTestcaseServiceImpl.java
+55
-25
PipelineService.java
...ain/java/cn/qg/holmes/service/gitlab/PipelineService.java
+9
-0
PipelineServiceImpl.java
...cn/qg/holmes/service/gitlab/impl/PipelineServiceImpl.java
+66
-0
JiraIssueService.java
...main/java/cn/qg/holmes/service/jira/JiraIssueService.java
+1
-1
DingRobotServiceImpl.java
.../cn/qg/holmes/service/jira/impl/DingRobotServiceImpl.java
+20
-12
JiraIssueServiceImpl.java
.../cn/qg/holmes/service/jira/impl/JiraIssueServiceImpl.java
+8
-2
JiraToDingding.java
src/main/java/cn/qg/holmes/task/jira/JiraToDingding.java
+20
-17
DingdingUtils.java
src/main/java/cn/qg/holmes/utils/DingdingUtils.java
+157
-42
GitlabService.java
src/main/java/cn/qg/holmes/utils/GitlabService.java
+68
-0
JenkinsService.java
src/main/java/cn/qg/holmes/utils/JenkinsService.java
+173
-0
SceneTestcaseMapper.xml
src/main/resources/mapper/auto/SceneTestcaseMapper.xml
+6
-1
TestcaseMapper.xml
src/main/resources/mapper/auto/TestcaseMapper.xml
+4
-1
No files found.
pom.xml
View file @
aa5d6cc8
...
...
@@ -136,6 +136,18 @@
<version>
5.2.0
</version>
</dependency>
<dependency>
<groupId>
com.offbytwo.jenkins
</groupId>
<artifactId>
jenkins-client
</artifactId>
<version>
0.3.8
</version>
</dependency>
<dependency>
<groupId>
org.gitlab
</groupId>
<artifactId>
java-gitlab-api
</artifactId>
<version>
4.1.1
</version>
</dependency>
</dependencies>
<build>
...
...
src/main/java/cn/qg/holmes/controller/auto/InterfaceController.java
View file @
aa5d6cc8
...
...
@@ -4,15 +4,19 @@ import cn.qg.holmes.common.JsonResult;
import
cn.qg.holmes.entity.auto.Interface
;
import
cn.qg.holmes.service.auto.AutoModuleService
;
import
cn.qg.holmes.service.auto.InterfaceService
;
import
com.alibaba.fastjson.JSON
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* 接口相关controller
...
...
@@ -106,4 +110,90 @@ public class InterfaceController {
}
return
JsonResult
.
buildSuccessResult
(
interfaceService
.
removeById
(
interfaceId
));
}
/**
* 解析CURL
* @param code curl代码
* @return
*/
@GetMapping
(
"/curl"
)
public
JsonResult
resolutionCurl
(
@RequestParam
String
code
)
{
List
<
Map
<
String
,
String
>>
headersList
=
new
ArrayList
<>();
List
<
Map
<
String
,
String
>>
parametersList
=
new
ArrayList
<>();
Map
<
String
,
Object
>
resultMap
=
new
HashMap
<>();
if
(
code
.
contains
(
"GET"
))
{
// 处理GET请求
String
getParameters
=
code
.
split
(
"\\?"
)[
1
];
// 去掉末尾的单引号
getParameters
=
getParameters
.
substring
(
0
,
getParameters
.
length
()-
1
);
String
[]
paramPair
=
getParameters
.
split
(
"&"
);
for
(
String
pair:
paramPair
)
{
String
[]
pairList
=
pair
.
split
(
"="
);
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"paramsName"
,
pairList
[
0
]);
map
.
put
(
"paramsValue"
,
pairList
[
1
]);
parametersList
.
add
(
map
);
}
}
else
if
(
code
.
contains
(
"POST"
))
{
// 处理POST请求
String
headerRegex
=
"--header '(.*)'"
;
String
parameterDataRegex
=
"--data-urlencode '(.*)'"
;
String
parameterFormRegex
=
"--form '(.*)'"
;
String
parameterJsonRegex
=
"--data-raw '(.*)'"
;
Pattern
headerPattern
=
Pattern
.
compile
(
headerRegex
);
Pattern
parameterDataPattern
=
Pattern
.
compile
(
parameterDataRegex
);
Pattern
parameterFormPattern
=
Pattern
.
compile
(
parameterFormRegex
);
Pattern
parameterJsonPattern
=
Pattern
.
compile
(
parameterJsonRegex
,
Pattern
.
DOTALL
);
Matcher
headerMatcher
=
headerPattern
.
matcher
(
code
);
Matcher
parameterDataMatcher
=
parameterDataPattern
.
matcher
(
code
);
Matcher
parameterFormMatcher
=
parameterFormPattern
.
matcher
(
code
);
Matcher
parameterJsonMatcher
=
parameterJsonPattern
.
matcher
(
code
);
while
(
headerMatcher
.
find
())
{
Map
<
String
,
String
>
headersMap
=
new
HashMap
<>();
String
headerItem
=
headerMatcher
.
group
(
1
);
String
[]
tempList
=
headerItem
.
split
(
":"
);
headersMap
.
put
(
"paramsName"
,
tempList
[
0
].
trim
());
headersMap
.
put
(
"paramsValue"
,
tempList
[
1
].
trim
());
headersList
.
add
(
headersMap
);
}
while
(
parameterDataMatcher
.
find
())
{
Map
<
String
,
String
>
parameterMap
=
new
HashMap
<>();
String
parameterItem
=
parameterDataMatcher
.
group
(
1
);
String
[]
tempList
=
parameterItem
.
split
(
"="
);
parameterMap
.
put
(
"paramsName"
,
tempList
[
0
].
trim
());
if
(
tempList
.
length
==
2
)
{
parameterMap
.
put
(
"paramsValue"
,
tempList
[
1
].
trim
());
}
else
{
parameterMap
.
put
(
"paramsValue"
,
""
);
}
parametersList
.
add
(
parameterMap
);
}
while
(
parameterFormMatcher
.
find
())
{
Map
<
String
,
String
>
parameterMap
=
new
HashMap
<>();
String
parameterItem
=
parameterFormMatcher
.
group
(
1
);
String
[]
tempList
=
parameterItem
.
split
(
"="
);
parameterMap
.
put
(
"paramsName"
,
tempList
[
0
].
trim
());
if
(
tempList
.
length
==
2
)
{
parameterMap
.
put
(
"paramsValue"
,
tempList
[
1
].
trim
());
}
else
{
parameterMap
.
put
(
"paramsValue"
,
""
);
}
parametersList
.
add
(
parameterMap
);
}
while
(
parameterJsonMatcher
.
find
())
{
Map
<
String
,
String
>
parameterMap
=
new
HashMap
<>();
String
parameterItem
=
parameterJsonMatcher
.
group
(
1
);
Map
<
String
,
Object
>
requestMap
=
JSON
.
parseObject
(
parameterItem
,
Map
.
class
);
for
(
Map
.
Entry
<
String
,
Object
>
entry:
requestMap
.
entrySet
())
{
parameterMap
.
put
(
"paramsName"
,
entry
.
getKey
());
parameterMap
.
put
(
"paramsValue"
,
entry
.
getValue
().
toString
());
parametersList
.
add
(
parameterMap
);
}
}
}
resultMap
.
put
(
"headersList"
,
headersList
);
resultMap
.
put
(
"parametersList"
,
parametersList
);
return
JsonResult
.
buildSuccessResult
(
resultMap
);
}
}
src/main/java/cn/qg/holmes/controller/auto/SceneTestcaseController.java
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
controller
.
auto
;
import
cn.qg.holmes.common.JsonResult
;
import
cn.qg.holmes.entity.auto.AutoModule
;
import
cn.qg.holmes.entity.auto.Interface
;
import
cn.qg.holmes.entity.auto.Scene
;
import
cn.qg.holmes.entity.auto.SceneTestcase
;
import
cn.qg.holmes.entity.auto.SceneTestcaseUpdateVo
;
import
cn.qg.holmes.service.auto.AutoModuleService
;
import
cn.qg.holmes.service.auto.InterfaceService
;
import
cn.qg.holmes.service.auto.SceneService
;
import
cn.qg.holmes.service.auto.SceneTestcaseService
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -17,11 +17,15 @@ import java.util.HashMap;
import
java.util.List
;
import
java.util.Map
;
@Slf4j
@CrossOrigin
@RestController
@RequestMapping
(
"/auto/sceneTestcase"
)
public
class
SceneTestcaseController
{
@Autowired
SceneService
sceneService
;
@Autowired
SceneTestcaseService
sceneTestcaseService
;
...
...
@@ -42,12 +46,12 @@ public class SceneTestcaseController {
return
JsonResult
.
buildErrorStateResult
(
"请传入场景id"
,
false
);
}
List
<
SceneTestcase
>
sceneTestcaseList
=
sceneTestcaseService
.
getSceneTestcaseListBySceneId
(
sceneId
);
for
(
SceneTestcase
sceneTestcase:
sceneTestcaseList
)
{
Interface
anInterface
=
interfaceService
.
getById
(
sceneTestcase
.
getInterfaceId
()
);
sceneTestcase
.
setInterfaceName
(
anInterface
.
getName
());
sceneTestcase
.
setModuleName
(
autoModuleService
.
getById
(
anInterface
.
getModuleId
()).
getName
());
}
return
JsonResult
.
buildSuccessResult
(
sceneTestcaseList
);
Scene
scene
=
sceneService
.
getById
(
sceneId
);
Map
<
String
,
Object
>
map
=
new
HashMap
<>(
);
map
.
put
(
"sceneId"
,
scene
.
getId
());
map
.
put
(
"globalParameters"
,
scene
.
getGlobalParameters
());
map
.
put
(
"sceneTestcaseList"
,
sceneTestcaseList
);
return
JsonResult
.
buildSuccessResult
(
map
);
}
/**
...
...
@@ -100,17 +104,27 @@ public class SceneTestcaseController {
public
JsonResult
saveOrUpdateSceneTestcaseList
(
@RequestBody
SceneTestcaseUpdateVo
sceneTestcaseUpdateVo
)
{
List
<
SceneTestcase
>
sceneTestcaseList
=
sceneTestcaseUpdateVo
.
getSceneTestcaseList
();
Integer
sceneId
=
sceneTestcaseUpdateVo
.
getSceneId
();
String
globalParameters
=
sceneTestcaseUpdateVo
.
getGlobalParameters
();
Scene
scene
=
sceneService
.
getById
(
sceneId
);
scene
.
setGlobalParameters
(
globalParameters
);
sceneService
.
saveOrUpdate
(
scene
);
log
.
info
(
"开始批量修改场景id为 {} 的场景用例:\n {}"
,
sceneId
,
sceneTestcaseList
);
List
<
SceneTestcase
>
sceneTestcaseListInDB
=
sceneTestcaseService
.
getSceneTestcaseListBySceneId
(
sceneId
);
log
.
info
(
"数据库中的场景用例为:{}"
,
sceneTestcaseListInDB
);
if
(
sceneTestcaseListInDB
.
size
()
>
0
)
{
for
(
SceneTestcase
sceneTestcaseInDB:
sceneTestcaseListInDB
)
{
Integer
DBId
=
sceneTestcaseInDB
.
getId
();
boolean
flag
=
false
;
for
(
SceneTestcase
sceneTestcase:
sceneTestcaseList
)
{
if
(
sceneTestcase
.
getId
().
equals
(
DBId
))
{
flag
=
true
;
// 过滤掉新增的
if
(
sceneTestcase
.
getId
()
!=
null
)
{
if
(
sceneTestcase
.
getId
().
equals
(
DBId
))
{
flag
=
true
;
}
}
}
if
(!
flag
)
{
log
.
info
(
"{}不在传入的list中,删除该条数据!"
,
sceneTestcaseInDB
);
sceneTestcaseService
.
removeById
(
sceneTestcaseInDB
.
getId
());
}
}
...
...
src/main/java/cn/qg/holmes/controller/auto/TestcaseController.java
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
controller
.
auto
;
import
cn.qg.holmes.common.JsonResult
;
import
cn.qg.holmes.entity.auto.Interface
;
import
cn.qg.holmes.entity.auto.Testcase
;
import
cn.qg.holmes.service.auto.InterfaceService
;
import
cn.qg.holmes.service.auto.TestcaseService
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
...
...
@@ -9,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.web.bind.annotation.*
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
...
...
@@ -23,6 +26,9 @@ public class TestcaseController {
@Autowired
TestcaseService
testcaseService
;
@Autowired
InterfaceService
interfaceService
;
/**
* 获取单接口用例列表
* @param moduleId 模块id
...
...
@@ -51,7 +57,13 @@ public class TestcaseController {
public
JsonResult
getTestcaseListByInterface
(
Integer
interfaceId
)
{
QueryWrapper
<
Testcase
>
testcaseQueryWrapper
=
new
QueryWrapper
<>();
testcaseQueryWrapper
.
eq
(
"interface_id"
,
interfaceId
);
return
JsonResult
.
buildSuccessResult
(
testcaseService
.
list
(
testcaseQueryWrapper
));
List
<
Testcase
>
testcaseList
=
testcaseService
.
list
(
testcaseQueryWrapper
);
Interface
anInterface
=
interfaceService
.
getById
(
interfaceId
);
for
(
Testcase
testcase:
testcaseList
)
{
testcase
.
setInterfaceName
(
anInterface
.
getName
());
testcase
.
setInterfaceUrl
(
anInterface
.
getUrl
());
}
return
JsonResult
.
buildSuccessResult
(
testcaseList
);
}
/**
...
...
src/main/java/cn/qg/holmes/controller/gitlab/GitlabController.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
controller
.
gitlab
;
import
cn.qg.holmes.common.JsonResult
;
import
cn.qg.holmes.utils.HttpClientUtils
;
import
com.alibaba.fastjson.JSON
;
import
org.springframework.web.bind.annotation.CrossOrigin
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.*
;
@CrossOrigin
@RestController
@RequestMapping
(
"/gitlab"
)
public
class
GitlabController
{
/**
* 获取项目名列表
* @return
*/
@GetMapping
(
"/projects"
)
public
JsonResult
getProjectsList
()
{
String
baseUrl
=
"http://qaapi.liangkebang.com/proconfig/get_project_for_jenkins?type="
;
String
javaResult
=
HttpClientUtils
.
doGet
(
baseUrl
+
"java"
);
String
uiResult
=
HttpClientUtils
.
doGet
(
baseUrl
+
"ui"
);
String
nodeResult
=
HttpClientUtils
.
doGet
(
baseUrl
+
"node"
);
List
<
String
>
javaList
=
Arrays
.
asList
(
javaResult
.
split
(
"\n"
));
List
<
String
>
uiList
=
Arrays
.
asList
(
uiResult
.
split
(
"\n"
));
List
<
String
>
nodeList
=
Arrays
.
asList
(
nodeResult
.
split
(
"\n"
));
List
<
Map
<
String
,
String
>>
serviceList
=
new
ArrayList
<>();
for
(
String
service:
javaList
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"name"
,
service
);
map
.
put
(
"type"
,
"java"
);
serviceList
.
add
(
map
);
}
for
(
String
service:
uiList
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"name"
,
service
);
map
.
put
(
"type"
,
"ui"
);
serviceList
.
add
(
map
);
}
for
(
String
service:
nodeList
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"name"
,
service
);
map
.
put
(
"type"
,
"node"
);
serviceList
.
add
(
map
);
}
return
JsonResult
.
buildSuccessResult
(
serviceList
);
}
/**
* 根据项目名获取分支列表
* @param projectName 项目名
* @return
*/
@GetMapping
(
"/branches"
)
public
JsonResult
getBranchesByProject
(
String
projectName
)
{
String
url
=
"https://qaapi.liangkebang.com/pipeline/getGitBranch?name="
+
projectName
;
return
JsonResult
.
buildSuccessResult
(
JSON
.
parseObject
(
HttpClientUtils
.
doGet
(
url
),
Map
.
class
));
}
}
src/main/java/cn/qg/holmes/controller/gitlab/JenkinsController.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
controller
.
gitlab
;
import
cn.qg.holmes.common.JsonResult
;
import
cn.qg.holmes.utils.JenkinsService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
@Slf4j
@CrossOrigin
@RestController
@RequestMapping
(
"/jenkins"
)
public
class
JenkinsController
{
@Autowired
JenkinsService
jenkinsService
;
/**
* 构建指定的jenkins job
* @param type 类型,java/ui/node
* @param project 项目名
* @param branch 分支名
* @param namespace 环境
* @return
*/
@GetMapping
(
"/build"
)
public
JsonResult
buildSpecifiedJob
(
@RequestParam
String
type
,
@RequestParam
String
project
,
@RequestParam
String
branch
,
@RequestParam
String
namespace
)
{
try
{
log
.
info
(
"开始构建jenkins项目:项目类型:{}, 项目名:{}, 分支:{}, 部署至环境:{}"
,
type
,
project
,
branch
,
namespace
);
jenkinsService
.
buildJenkinsJob
(
type
,
project
,
branch
,
namespace
);
return
JsonResult
.
buildSuccessResult
(
true
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
JsonResult
.
buildErrorStateResult
(
"构建失败!"
,
false
);
}
}
}
src/main/java/cn/qg/holmes/controller/gitlab/PipelineController.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
controller
.
gitlab
;
import
cn.qg.holmes.common.JsonResult
;
import
cn.qg.holmes.entity.gitlab.DingRobotPipelineVo
;
import
cn.qg.holmes.entity.gitlab.Pipeline
;
import
cn.qg.holmes.entity.jira.DingRobot
;
import
cn.qg.holmes.service.gitlab.PipelineService
;
import
cn.qg.holmes.service.jira.DingRobotService
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.BufferedReader
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@Slf4j
@RestController
@CrossOrigin
@RequestMapping
(
"/pipeline"
)
public
class
PipelineController
{
@Autowired
PipelineService
pipelineService
;
@Autowired
DingRobotService
dingRobotService
;
/**
* gitlab webhook
* @param request
*/
@PostMapping
(
"/webhook"
)
public
void
piplineWebhook
(
HttpServletRequest
request
)
{
StringBuilder
piplineData
=
new
StringBuilder
();
try
{
BufferedReader
br
=
request
.
getReader
();
String
str
=
""
;
while
((
str
=
br
.
readLine
())
!=
null
){
piplineData
.
append
(
str
);
}
br
.
close
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
log
.
info
(
"收到gitlab推送来的数据:{}"
,
piplineData
);
pipelineService
.
buildPipelineJob
(
String
.
valueOf
(
piplineData
));
}
@GetMapping
(
"/list"
)
public
JsonResult
getDingRobotAndPipelineList
(
@RequestParam
Integer
pageNum
,
@RequestParam
Integer
pageSize
)
{
IPage
<
DingRobot
>
page
=
new
Page
<>(
pageNum
,
pageSize
);
QueryWrapper
<
DingRobot
>
dingRobotQueryWrapper
=
new
QueryWrapper
();
dingRobotQueryWrapper
.
orderByDesc
(
"id"
);
IPage
<
DingRobot
>
projectRobotIPage
=
dingRobotService
.
page
(
page
,
dingRobotQueryWrapper
);
List
<
DingRobot
>
dingRobotList
=
projectRobotIPage
.
getRecords
();
List
<
DingRobotPipelineVo
>
dingRobotPipelineVoList
=
new
ArrayList
<>();
for
(
DingRobot
dingRobot:
dingRobotList
)
{
DingRobotPipelineVo
dingRobotPipelineVo
=
new
DingRobotPipelineVo
();
dingRobotPipelineVo
.
setDingRobot
(
dingRobot
);
QueryWrapper
<
Pipeline
>
pipelineQueryWrapper
=
new
QueryWrapper
<>();
pipelineQueryWrapper
.
eq
(
"ding_robot_id"
,
dingRobot
.
getId
());
List
<
Pipeline
>
pipelineList
=
pipelineService
.
list
(
pipelineQueryWrapper
);
dingRobotPipelineVo
.
setPipelineList
(
pipelineList
);
dingRobotPipelineVoList
.
add
(
dingRobotPipelineVo
);
}
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"total"
,
projectRobotIPage
.
getTotal
());
map
.
put
(
"list"
,
dingRobotPipelineVoList
);
return
JsonResult
.
buildSuccessResult
(
map
);
}
/**
* 新增ding robot 以及对应的pipeline
* @return
*/
@PostMapping
(
"/add"
)
public
JsonResult
addRobotAndPipeline
(
@RequestBody
DingRobotPipelineVo
dingRobotPipelineVo
)
{
try
{
DingRobot
dingRobot
=
dingRobotPipelineVo
.
getDingRobot
();
String
projectName
=
dingRobot
.
getProjectName
();
String
jiraProjectKey
=
dingRobot
.
getJiraProjectKey
();
QueryWrapper
<
DingRobot
>
dingRobotQueryWrapper
=
new
QueryWrapper
<>();
dingRobotQueryWrapper
.
eq
(
"jira_project_key"
,
jiraProjectKey
);
dingRobotQueryWrapper
.
eq
(
"project_name"
,
projectName
);
// 根据jira project key和项目名判断是否已存在
if
(
dingRobotService
.
getOne
(
dingRobotQueryWrapper
)
!=
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"项目已存在"
,
false
);
}
boolean
dingRobotResult
=
dingRobotService
.
save
(
dingRobot
);
if
(!
dingRobotResult
)
{
return
JsonResult
.
buildErrorStateResult
(
"服务器异常,保存失败!"
,
false
);
}
// 获取该robot id,并赋值给pipelineList
DingRobot
dingRobotNew
=
dingRobotService
.
getOne
(
dingRobotQueryWrapper
);
Integer
dingRobotId
=
dingRobotNew
.
getId
();
List
<
Pipeline
>
pipelineList
=
dingRobotPipelineVo
.
getPipelineList
();
// 判断pipelineList是否为空
if
(
pipelineList
.
size
()
>
0
)
{
for
(
Pipeline
pipeline:
pipelineList
)
{
pipeline
.
setDingRobotId
(
dingRobotId
);
}
pipelineService
.
saveBatch
(
pipelineList
);
}
return
JsonResult
.
buildSuccessResult
(
true
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
JsonResult
.
buildErrorStateResult
(
"新增失败"
,
false
);
}
}
/**
* 修改pipeline
* @param dingRobotPipelineVo
* @return
*/
@PostMapping
(
"/modify"
)
public
JsonResult
modifyPipeline
(
@RequestBody
DingRobotPipelineVo
dingRobotPipelineVo
)
{
try
{
DingRobot
dingRobot
=
dingRobotPipelineVo
.
getDingRobot
();
boolean
dingRobotResult
=
dingRobotService
.
saveOrUpdate
(
dingRobot
);
if
(!
dingRobotResult
)
{
return
JsonResult
.
buildErrorStateResult
(
"修改失败!"
,
false
);
}
Integer
dingRobotId
=
dingRobot
.
getId
();
List
<
Pipeline
>
pipelineList
=
dingRobotPipelineVo
.
getPipelineList
();
QueryWrapper
<
Pipeline
>
pipelineQueryWrapper
=
new
QueryWrapper
<>();
pipelineQueryWrapper
.
eq
(
"ding_robot_id"
,
dingRobotId
);
List
<
Pipeline
>
pipelineListInDb
=
pipelineService
.
list
(
pipelineQueryWrapper
);
// 判断是否有删除的部分
if
(
pipelineListInDb
.
size
()
>
0
)
{
for
(
Pipeline
pipelineDb:
pipelineListInDb
)
{
boolean
flag
=
false
;
if
(
pipelineList
.
size
()
>
0
)
{
for
(
Pipeline
pipeline:
pipelineList
)
{
if
(
pipelineDb
.
getId
().
equals
(
pipeline
.
getId
()))
{
flag
=
true
;
break
;
}
}
}
if
(!
flag
)
{
pipelineService
.
removeById
(
pipelineDb
.
getId
());
}
}
}
// 判断是否有新增的
for
(
Pipeline
pipeline:
pipelineList
)
{
if
(
pipeline
.
getId
()
==
null
)
{
pipeline
.
setDingRobotId
(
dingRobotId
);
}
}
// 剩下的直接更新
pipelineService
.
saveOrUpdateBatch
(
pipelineList
);
return
JsonResult
.
buildSuccessResult
(
true
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
JsonResult
.
buildErrorStateResult
(
"修改失败!"
,
false
);
}
}
/**
* 删除pipeline
* @param dingRobotId
* @return
*/
@GetMapping
(
"/delete"
)
public
JsonResult
deletePipeline
(
@RequestParam
Integer
dingRobotId
)
{
try
{
if
(
dingRobotService
.
getById
(
dingRobotId
)
!=
null
)
{
dingRobotService
.
removeById
(
dingRobotId
);
}
QueryWrapper
<
Pipeline
>
pipelineQueryWrapper
=
new
QueryWrapper
<>();
pipelineQueryWrapper
.
eq
(
"ding_robot_id"
,
dingRobotId
);
if
(
pipelineService
.
list
(
pipelineQueryWrapper
)
!=
null
)
{
pipelineService
.
remove
(
pipelineQueryWrapper
);
}
return
JsonResult
.
buildSuccessResult
(
true
);
}
catch
(
Exception
e
)
{
return
JsonResult
.
buildErrorStateResult
(
"删除失败"
,
false
);
}
}
}
src/main/java/cn/qg/holmes/controller/jira/JiraController.java
View file @
aa5d6cc8
This diff is collapsed.
Click to expand it.
src/main/java/cn/qg/holmes/controller/jira/JiraWebhookController.java
deleted
100644 → 0
View file @
f3d3077d
package
cn
.
qg
.
holmes
.
controller
.
jira
;
import
cn.qg.holmes.common.JsonResult
;
import
cn.qg.holmes.entity.jira.DingRobot
;
import
cn.qg.holmes.service.jira.DingRobotService
;
import
cn.qg.holmes.service.jira.JiraIssueService
;
import
com.atlassian.jira.rest.client.api.domain.BasicProject
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.BufferedReader
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@Slf4j
@CrossOrigin
@RestController
@RequestMapping
(
"/jira"
)
public
class
JiraWebhookController
{
@Autowired
DingRobotService
dingRobotService
;
@Autowired
JiraIssueService
jiraIssueService
;
/**
* jira webhook
* @param request
*/
@PostMapping
(
"/webhook"
)
public
void
jiraWebhook
(
HttpServletRequest
request
)
{
try
{
BufferedReader
br
=
request
.
getReader
();
StringBuilder
jiraData
=
new
StringBuilder
();
String
str
=
""
;
while
((
str
=
br
.
readLine
())
!=
null
){
jiraData
.
append
(
str
);
}
br
.
close
();
dingRobotService
.
sendMsgToDing
(
String
.
valueOf
(
jiraData
));
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
/**
* 获取Jira项目列表
* @return
* @throws Exception
*/
@GetMapping
(
"/list/project"
)
public
JsonResult
getJiraProjectKey
()
throws
Exception
{
List
<
Map
<
String
,
String
>>
jiraKeyList
=
new
ArrayList
<>();
Iterable
<
BasicProject
>
projects
=
jiraIssueService
.
getJiraProjectList
();
for
(
BasicProject
project:
projects
)
{
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"id"
,
project
.
getId
().
toString
());
map
.
put
(
"key"
,
project
.
getKey
());
map
.
put
(
"name"
,
project
.
getName
());
jiraKeyList
.
add
(
map
);
}
return
JsonResult
.
buildSuccessResult
(
jiraKeyList
);
}
/**
* 项目机器人列表
* @param pageNum 第几页
* @param pageSize 每页多少个
* @return
*/
@GetMapping
(
"/list/robot"
)
public
JsonResult
getProjectRobotList
(
Integer
pageNum
,
Integer
pageSize
)
{
IPage
<
DingRobot
>
page
=
new
Page
<>(
pageNum
,
pageSize
);
QueryWrapper
<
DingRobot
>
dingRobotQueryWrapper
=
new
QueryWrapper
();
dingRobotQueryWrapper
.
orderByDesc
(
"id"
);
IPage
<
DingRobot
>
projectRobotIPage
=
dingRobotService
.
page
(
page
,
dingRobotQueryWrapper
);
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"total"
,
projectRobotIPage
.
getTotal
());
map
.
put
(
"list"
,
projectRobotIPage
.
getRecords
());
return
JsonResult
.
buildSuccessResult
(
map
);
}
/**
* 新增项目机器人
* @param dingRobot 项目机器人实体
* @return
*/
@PostMapping
(
"/add/robot"
)
public
JsonResult
addProjectRobot
(
@RequestBody
DingRobot
dingRobot
)
{
if
(
dingRobot
.
getProjectName
()
==
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"项目名称不能为空!"
,
false
);
}
if
(
dingRobot
.
getDingUrl
()
==
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"钉钉url不能为空!"
,
false
);
}
return
JsonResult
.
buildSuccessResult
(
dingRobotService
.
save
(
dingRobot
));
}
/**
* 修改项目机器人
* @param dingRobot 项目机器人实体
* @return
*/
@PostMapping
(
"/modify/robot"
)
public
JsonResult
editProjectRobot
(
@RequestBody
DingRobot
dingRobot
)
{
if
(
dingRobot
.
getId
()
==
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"id不能为空!"
,
false
);
}
if
(
dingRobot
.
getProjectName
()
==
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"项目名称不能为空!"
,
false
);
}
if
(
dingRobot
.
getDingUrl
()
==
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"钉钉url不能为空!"
,
false
);
}
return
JsonResult
.
buildSuccessResult
(
dingRobotService
.
updateById
(
dingRobot
));
}
/**
* 删除项目机器人
* @param projectRobotId 项目机器人实体id
* @return
*/
@GetMapping
(
"/delete/robot"
)
public
JsonResult
deleteProjectRobot
(
Integer
projectRobotId
)
{
if
(
dingRobotService
.
getById
(
projectRobotId
)
==
null
)
{
return
JsonResult
.
buildErrorStateResult
(
"项目机器人不存在!"
,
false
);
}
return
JsonResult
.
buildSuccessResult
(
dingRobotService
.
removeById
(
projectRobotId
));
}
}
src/main/java/cn/qg/holmes/entity/auto/Scene.java
View file @
aa5d6cc8
...
...
@@ -20,6 +20,7 @@ public class Scene {
private
Integer
id
;
private
String
name
;
private
Integer
projectId
;
private
String
globalParameters
;
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
createTime
;
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
...
...
src/main/java/cn/qg/holmes/entity/auto/SceneTestcase.java
View file @
aa5d6cc8
...
...
@@ -20,6 +20,7 @@ public class SceneTestcase {
private
Integer
id
;
private
Integer
sceneId
;
private
Integer
interfaceId
;
private
String
name
;
private
String
preAction
;
private
String
postAction
;
private
String
headers
;
...
...
@@ -36,5 +37,7 @@ public class SceneTestcase {
@TableField
(
exist
=
false
)
private
String
interfaceName
;
@TableField
(
exist
=
false
)
private
String
interfaceUrl
;
@TableField
(
exist
=
false
)
private
String
moduleName
;
}
src/main/java/cn/qg/holmes/entity/auto/SceneTestcaseReport.java
View file @
aa5d6cc8
...
...
@@ -21,6 +21,7 @@ public class SceneTestcaseReport {
private
Integer
sceneTestcaseId
;
private
String
interfaceUrl
;
private
String
interfaceName
;
private
String
testcaseName
;
private
String
url
;
private
String
headers
;
private
String
parameters
;
...
...
src/main/java/cn/qg/holmes/entity/auto/SceneTestcaseUpdateVo.java
View file @
aa5d6cc8
...
...
@@ -7,5 +7,6 @@ import java.util.List;
@Data
public
class
SceneTestcaseUpdateVo
{
Integer
sceneId
;
String
globalParameters
;
List
<
SceneTestcase
>
sceneTestcaseList
;
}
src/main/java/cn/qg/holmes/entity/auto/Testcase.java
View file @
aa5d6cc8
...
...
@@ -35,5 +35,7 @@ public class Testcase {
@TableField
(
exist
=
false
)
private
String
interfaceName
;
@TableField
(
exist
=
false
)
private
String
interfaceUrl
;
@TableField
(
exist
=
false
)
private
String
moduleName
;
}
src/main/java/cn/qg/holmes/entity/gitlab/DingRobotPipelineVo.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
entity
.
gitlab
;
import
cn.qg.holmes.entity.jira.DingRobot
;
import
lombok.Data
;
import
java.util.List
;
/**
* 新增/编辑jira通知-pipeline实体
*/
@Data
public
class
DingRobotPipelineVo
{
private
DingRobot
dingRobot
;
private
List
<
Pipeline
>
pipelineList
;
}
src/main/java/cn/qg/holmes/entity/gitlab/Pipeline.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
entity
.
gitlab
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.Data
;
import
java.util.Date
;
@Data
public
class
Pipeline
{
@TableId
(
type
=
IdType
.
AUTO
)
private
Integer
id
;
private
Integer
dingRobotId
;
private
String
serviceName
;
private
String
serviceBranch
;
private
String
serviceType
;
private
String
namespace
;
private
Integer
enable
;
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
createTime
;
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
updateTime
;
}
src/main/java/cn/qg/holmes/entity/jira/DingRobot.java
View file @
aa5d6cc8
...
...
@@ -17,6 +17,7 @@ public class DingRobot {
private
String
jiraProjectKey
;
private
String
dingUrl
;
private
String
creator
;
private
String
namespace
;
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
createTime
;
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
...
...
src/main/java/cn/qg/holmes/entity/jira/SendSmokingResultVo.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
entity
.
jira
;
import
lombok.Data
;
@Data
public
class
SendSmokingResultVo
{
private
String
jiraProjectKey
;
private
String
testProjectName
;
private
String
progress
;
private
Boolean
result
;
private
String
risk
;
private
String
webhook
;
}
src/main/java/cn/qg/holmes/mapper/gitlab/PipelineMapper.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
mapper
.
gitlab
;
import
cn.qg.holmes.entity.gitlab.Pipeline
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
public
interface
PipelineMapper
extends
BaseMapper
<
Pipeline
>
{
}
src/main/java/cn/qg/holmes/service/auto/AutoUtilsService.java
View file @
aa5d6cc8
...
...
@@ -6,13 +6,15 @@ import java.util.UUID;
public
interface
AutoUtilsService
{
Map
<
String
,
String
>
replaceHeaders
(
String
headers
,
String
variables
,
UUID
uuid
);
boolean
extractResponse
(
String
response
,
String
extract
,
UUID
uuid
);
Map
<
String
,
String
>
replaceParameters
(
String
parameters
,
String
variables
,
UUID
uuid
);
Map
<
String
,
Object
>
extractResponseNew
(
String
response
,
String
extract
);
Map
<
String
,
String
>
replaceVariables
(
String
parameters
,
UUID
uuid
);
boolean
extractResponse
(
String
response
,
String
extract
,
UUID
uuid
);
Map
<
String
,
String
>
replaceVariablesNew
(
String
parameters
,
Map
<
String
,
Object
>
globalMap
);
boolean
assertResponse
(
String
response
,
List
<
Map
>
validateList
);
Map
<
String
,
Object
>
handlePreCondition
(
String
namespace
,
String
preString
,
Map
<
String
,
Object
>
globalMap
);
}
src/main/java/cn/qg/holmes/service/auto/impl/AutoUtilsServiceImpl.java
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
service
.
auto
.
impl
;
import
cn.qg.holmes.service.auto.AutoUtilsService
;
import
cn.qg.holmes.utils.HttpClientUtils
;
import
cn.qg.holmes.utils.RedisUtils
;
import
com.alibaba.fastjson.JSON
;
import
com.jayway.jsonpath.JsonPath
;
...
...
@@ -8,9 +9,12 @@ import lombok.extern.slf4j.Slf4j;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.UUID
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* @author libo
...
...
@@ -24,58 +28,38 @@ public class AutoUtilsServiceImpl implements AutoUtilsService {
RedisUtils
redisUtils
;
/**
* 将请求headers中的变量替换成对应的值
* @param headers 请求头json
* @param variables 参数json
* @return
*/
public
Map
<
String
,
String
>
replaceHeaders
(
String
headers
,
String
variables
,
UUID
uuid
)
{
log
.
info
(
"开始执行请求头替换!"
);
Map
<
String
,
String
>
headersMap
=
JSON
.
parseObject
(
headers
,
Map
.
class
);
Map
<
String
,
String
>
varMap
=
JSON
.
parseObject
(
variables
,
Map
.
class
);
log
.
info
(
"替换之前的headers:{}"
,
headersMap
);
log
.
info
(
"参数列表:{}"
,
varMap
);
for
(
String
key:
varMap
.
keySet
())
{
String
value
=
varMap
.
get
(
key
);
headersMap
.
put
(
key
,
redisUtils
.
get
(
uuid
+
"_"
+
value
.
substring
(
1
)).
toString
());
}
log
.
info
(
"替换之后的headers:{}"
,
headersMap
);
return
headersMap
;
}
/**
* 将请求体中的变量替换成对应的值
* @param parameters 请求参数json
* @param variables 变量json
* @return 替换后的参数Map
* 参数替换-新
* @param parameters headers或者parameters
* @param uuid 唯一标识
*/
public
Map
<
String
,
String
>
replaceParameters
(
String
parameters
,
String
variables
,
UUID
uuid
)
{
log
.
info
(
"开始执行请求参数替换!"
);
@Override
public
Map
<
String
,
String
>
replaceVariables
(
String
parameters
,
UUID
uuid
)
{
Map
<
String
,
String
>
parameterMap
=
JSON
.
parseObject
(
parameters
,
Map
.
class
);
Map
<
String
,
String
>
varMap
=
JSON
.
parseObject
(
variables
,
Map
.
class
);
log
.
info
(
"替换之前的参数:{}"
,
parameterMap
);
log
.
info
(
"参数列表:{}"
,
varMap
);
for
(
String
key:
varMap
.
keySet
())
{
String
value
=
varMap
.
get
(
key
);
parameterMap
.
put
(
key
,
redisUtils
.
get
(
uuid
+
"_"
+
value
.
substring
(
1
)).
toString
());
for
(
String
key:
parameterMap
.
keySet
())
{
String
value
=
parameterMap
.
get
(
key
);
if
(
value
.
startsWith
(
"$"
))
{
parameterMap
.
put
(
key
,
redisUtils
.
get
(
uuid
+
"_"
+
value
.
substring
(
1
)).
toString
());
}
}
log
.
info
(
"替换之后的参数:{}"
,
parameterMap
);
return
parameterMap
;
}
/**
* 参数替换-新
* @param parameters headers或者parameters
* @param uuid 唯一标识
* 新的参数替换,不再从redis里取值,而是从全局Map中取值
* @param parameters
* @param globalMap
* @return
*/
@Override
public
Map
<
String
,
String
>
replaceVariables
(
String
parameters
,
UUID
uuid
)
{
public
Map
<
String
,
String
>
replaceVariables
New
(
String
parameters
,
Map
<
String
,
Object
>
globalMap
)
{
Map
<
String
,
String
>
parameterMap
=
JSON
.
parseObject
(
parameters
,
Map
.
class
);
log
.
info
(
"替换之前的参数:{}"
,
parameterMap
);
for
(
String
key:
parameterMap
.
keySet
())
{
String
value
=
parameterMap
.
get
(
key
);
if
(
value
.
startsWith
(
"$"
))
{
parameterMap
.
put
(
key
,
redisUtils
.
get
(
uuid
+
"_"
+
value
.
substring
(
1
)).
toString
());
parameterMap
.
put
(
key
,
globalMap
.
get
(
value
.
substring
(
1
)).
toString
());
}
}
log
.
info
(
"替换之后的参数:{}"
,
parameterMap
);
...
...
@@ -94,7 +78,20 @@ public class AutoUtilsServiceImpl implements AutoUtilsService {
for
(
String
key:
extractMap
.
keySet
())
{
String
value
=
extractMap
.
get
(
key
);
String
redisKey
=
uuid
+
"_"
+
key
;
redisUtils
.
set
(
redisKey
,
JsonPath
.
read
(
response
,
value
));
String
redisValue
=
""
;
if
(
value
.
startsWith
(
"$"
))
{
redisValue
=
JsonPath
.
read
(
response
,
value
);
}
else
{
Pattern
pattern
=
Pattern
.
compile
(
value
);
Matcher
matcher
=
pattern
.
matcher
(
response
);
if
(
matcher
.
find
())
{
redisValue
=
matcher
.
group
(
1
);
}
else
{
return
false
;
}
}
// redisUtils.set(redisKey, JsonPath.read(response, value));
redisUtils
.
set
(
redisKey
,
redisValue
);
redisUtils
.
expire
(
redisKey
,
120
);
}
}
catch
(
Exception
e
)
{
...
...
@@ -104,6 +101,35 @@ public class AutoUtilsServiceImpl implements AutoUtilsService {
return
true
;
}
@Override
public
Map
<
String
,
Object
>
extractResponseNew
(
String
response
,
String
extract
)
{
Map
<
String
,
Object
>
resultMap
=
new
HashMap
<>();
try
{
Map
<
String
,
String
>
extractMap
=
JSON
.
parseObject
(
extract
,
Map
.
class
);
for
(
String
key:
extractMap
.
keySet
())
{
String
value
=
extractMap
.
get
(
key
);
String
extractValue
=
""
;
// 如果以$开头,则使用JsonPath解析
if
(
value
.
startsWith
(
"$"
))
{
extractValue
=
JsonPath
.
read
(
response
,
value
);
}
else
{
Pattern
pattern
=
Pattern
.
compile
(
value
);
Matcher
matcher
=
pattern
.
matcher
(
response
);
if
(
matcher
.
find
())
{
extractValue
=
matcher
.
group
(
1
);
}
else
{
return
null
;
}
}
resultMap
.
put
(
key
,
extractValue
);
}
return
resultMap
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
resultMap
;
}
}
/**
* 响应断言
* @return
...
...
@@ -121,6 +147,65 @@ public class AutoUtilsServiceImpl implements AutoUtilsService {
return
true
;
}
/**
*
* @param namespace
* @param preString
* @return
*/
@Override
public
Map
<
String
,
Object
>
handlePreCondition
(
String
namespace
,
String
preString
,
Map
<
String
,
Object
>
globalMap
)
{
log
.
info
(
"开始处理前置动作!"
);
Map
<
String
,
Object
>
resultMap
=
new
HashMap
<>();
try
{
List
<
Map
>
preList
=
JSON
.
parseArray
(
preString
,
Map
.
class
);
for
(
Map
<
String
,
Object
>
map:
preList
)
{
String
db
=
map
.
get
(
"db"
).
toString
();
String
sql
=
map
.
get
(
"sql"
).
toString
();
String
key
=
null
;
String
type
=
null
;
if
(
map
.
get
(
"key"
)
!=
null
)
{
key
=
map
.
get
(
"key"
).
toString
();
}
if
(
map
.
get
(
"type"
)
!=
null
)
{
type
=
map
.
get
(
"type"
).
toString
();
}
// 确认SQL中是否需要变量替换
String
regex
=
"(\\{\\{[A-Za-z0-9]+}})"
;
Pattern
pattern
=
Pattern
.
compile
(
regex
);
Matcher
matcher
=
pattern
.
matcher
(
sql
);
while
(
matcher
.
find
())
{
String
replace
=
matcher
.
group
();
// 去掉首位的{{和}}
String
tempKey
=
replace
.
substring
(
2
,
replace
.
length
()
-
2
);
sql
=
sql
.
replace
(
replace
,
"'"
+
globalMap
.
get
(
tempKey
).
toString
()
+
"'"
);
}
Map
<
String
,
String
>
params
=
new
HashMap
<>();
params
.
put
(
"namespace"
,
namespace
);
params
.
put
(
"database"
,
db
);
params
.
put
(
"sql"
,
sql
);
params
.
put
(
"type"
,
type
);
String
url
=
"https://qa-platform-yxm.liangkebang.net/sql/execute"
;
String
result
=
HttpClientUtils
.
doGet
(
url
,
params
);
log
.
info
(
"开始执行SQL:{}"
,
sql
);
log
.
info
(
"SQL返回结果:{}"
,
result
);
// 只有select才需要加入Map
if
(
sql
.
startsWith
(
"select"
)
||
sql
.
startsWith
(
"SELECT"
))
{
if
(
type
.
equals
(
"map"
))
{
resultMap
.
put
(
key
,
JsonPath
.
read
(
result
,
"$.data."
+
key
));
}
else
if
(
type
.
equals
(
"list"
))
{
resultMap
.
put
(
key
,
JsonPath
.
read
(
result
,
"$.data."
));
}
}
}
log
.
info
(
"前置动作获取到的值:{}"
,
resultMap
);
return
resultMap
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
*
* @param comparator
...
...
src/main/java/cn/qg/holmes/service/auto/impl/SceneTestcaseServiceImpl.java
View file @
aa5d6cc8
...
...
@@ -47,16 +47,41 @@ public class SceneTestcaseServiceImpl extends ServiceImpl<SceneTestcaseMapper, S
@Autowired
SceneService
sceneService
;
/**
* 执行场景用例
* @param namespace 环境
* @param sceneId 场景id
* @param batch 批次号
* @return
*/
@Override
public
String
executeSceneTestcase
(
String
namespace
,
Integer
sceneId
,
String
batch
)
{
UUID
uuid
=
UUID
.
randomUUID
();
QueryWrapper
queryWrapper
=
new
QueryWrapper
();
QueryWrapper
<
SceneTestcase
>
queryWrapper
=
new
QueryWrapper
<>();
queryWrapper
.
eq
(
"scene_id"
,
sceneId
);
queryWrapper
.
orderByAsc
(
"sequence"
);
List
<
SceneTestcase
>
sceneTestcaseList
=
sceneTestcaseMapper
.
selectList
(
queryWrapper
);
List
<
Map
<
String
,
Object
>>
resultList
=
new
ArrayList
<>();
String
globalParameters
=
sceneService
.
getById
(
sceneId
).
getGlobalParameters
();
// 全局变量Map
Map
<
String
,
Object
>
globalMap
=
new
HashMap
<>();
if
(
globalParameters
!=
null
)
{
globalMap
.
putAll
(
JSON
.
parseObject
(
globalParameters
,
Map
.
class
));
}
for
(
SceneTestcase
sceneTestcase:
sceneTestcaseList
)
{
resultList
.
add
(
JSON
.
parseObject
(
sceneTestcaseExecution
(
namespace
,
sceneId
,
sceneTestcase
.
getInterfaceId
(),
uuid
,
batch
),
Map
.
class
));
String
preAction
=
sceneTestcase
.
getPreAction
();
if
(
preAction
!=
null
&&
!
preAction
.
isEmpty
())
{
Map
<
String
,
Object
>
preMap
=
autoUtilsService
.
handlePreCondition
(
namespace
,
preAction
,
globalMap
);
if
(
preMap
!=
null
)
{
globalMap
.
putAll
(
preMap
);
}
}
// resultList.add(JSON.parseObject(sceneTestcaseExecution(namespace, sceneId, sceneTestcase.getInterfaceId(), sceneTestcase.getSequence(), uuid, batch), Map.class));
Map
<
String
,
Object
>
tempMap
=
sceneTestcaseExecution
(
namespace
,
sceneId
,
sceneTestcase
.
getInterfaceId
(),
sceneTestcase
.
getSequence
(),
batch
,
globalMap
);
Map
<
String
,
Object
>
reportMap
=
(
Map
<
String
,
Object
>)
tempMap
.
get
(
"report"
);
Map
<
String
,
Object
>
extractMap
=
(
Map
<
String
,
Object
>)
tempMap
.
get
(
"extract"
);
resultList
.
add
(
reportMap
);
// 将解析出来的值放入全局变量Map
globalMap
.
putAll
(
extractMap
);
}
return
JSON
.
toJSONString
(
resultList
);
}
...
...
@@ -71,10 +96,11 @@ public class SceneTestcaseServiceImpl extends ServiceImpl<SceneTestcaseMapper, S
return
sceneTestcaseMapper
.
getSceneTestcaseListBySceneId
(
sceneId
);
}
public
String
sceneTestcaseExecution
(
String
namespace
,
Integer
sceneId
,
Integer
interfaceId
,
UUID
uuid
,
String
batch
)
{
QueryWrapper
queryWrapper
=
new
QueryWrapper
();
public
Map
<
String
,
Object
>
sceneTestcaseExecution
(
String
namespace
,
Integer
sceneId
,
Integer
interfaceId
,
Integer
sequence
,
String
batch
,
Map
<
String
,
Object
>
globalMap
)
{
QueryWrapper
<
SceneTestcase
>
queryWrapper
=
new
QueryWrapper
();
queryWrapper
.
eq
(
"scene_id"
,
sceneId
);
queryWrapper
.
eq
(
"interface_id"
,
interfaceId
);
queryWrapper
.
eq
(
"sequence"
,
sequence
);
SceneTestcase
sceneTestcase
=
sceneTestcaseMapper
.
selectOne
(
queryWrapper
);
Interface
anInterface
=
interfaceService
.
getById
(
interfaceId
);
AutoModule
autoModule
=
autoModuleService
.
getById
(
anInterface
.
getModuleId
());
...
...
@@ -90,19 +116,13 @@ public class SceneTestcaseServiceImpl extends ServiceImpl<SceneTestcaseMapper, S
String
validate
=
sceneTestcase
.
getValidate
();
Map
<
String
,
String
>
parameterMap
=
JSON
.
parseObject
(
parameters
,
Map
.
class
);
Map
<
String
,
String
>
headersMap
=
JSON
.
parseObject
(
headers
,
Map
.
class
);
// 使用变量替换headers
// if (variables != null && !variables.isEmpty() && headers != null && !headers.isEmpty()) {
// headersMap = autoUtilsService.replaceHeaders(headers, variables, uuid);
// }
if
(
headers
!=
null
&&
!
headers
.
isEmpty
())
{
headersMap
=
autoUtilsService
.
replaceVariables
(
headers
,
uuid
);
// headersMap = autoUtilsService.replaceVariables(headers, uuid);
headersMap
=
autoUtilsService
.
replaceVariablesNew
(
headers
,
globalMap
);
}
// 使用变量替换参数
// if (variables != null && !variables.isEmpty() && parameters != null && !parameters.isEmpty()) {
// parameterMap = autoUtilsService.replaceParameters(parameters, variables, uuid);
// }
if
(
parameters
!=
null
&&
!
parameters
.
isEmpty
())
{
parameterMap
=
autoUtilsService
.
replaceVariables
(
parameters
,
uuid
);
// parameterMap = autoUtilsService.replaceVariables(parameters, uuid);
parameterMap
=
autoUtilsService
.
replaceVariablesNew
(
parameters
,
globalMap
);
}
// 创建断言列表
List
<
Map
>
validateList
=
new
ArrayList
<>();
...
...
@@ -136,17 +156,23 @@ public class SceneTestcaseServiceImpl extends ServiceImpl<SceneTestcaseMapper, S
assertResult
=
autoUtilsService
.
assertResponse
(
response
,
validateList
);
}
// 解析响应
Map
<
String
,
Object
>
extractMap
=
new
HashMap
<>();
if
(
extract
!=
null
&&
!
extract
.
isEmpty
())
{
autoUtilsService
.
extractResponse
(
response
,
extract
,
uuid
);
// autoUtilsService.extractResponse(response, extract, uuid);
extractMap
=
autoUtilsService
.
extractResponseNew
(
response
,
extract
);
}
Map
<
String
,
Object
>
reportMap
=
new
HashMap
<>();
reportMap
.
put
(
"url"
,
url
);
reportMap
.
put
(
"name"
,
interfaceName
);
reportMap
.
put
(
"headers"
,
headersMap
);
reportMap
.
put
(
"parameters"
,
parameterMap
);
reportMap
.
put
(
"assertResult"
,
assertResult
);
reportMap
.
put
(
"elapsedTime"
,
elapsedTime
);
try
{
reportMap
.
put
(
"response"
,
JSON
.
parseObject
(
response
,
Map
.
class
));
}
catch
(
Exception
e
)
{
reportMap
.
put
(
"response"
,
response
);
}
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"url"
,
url
);
map
.
put
(
"name"
,
interfaceName
);
map
.
put
(
"headers"
,
headersMap
);
map
.
put
(
"parameters"
,
parameterMap
);
map
.
put
(
"assertResult"
,
assertResult
);
map
.
put
(
"response"
,
JSON
.
parseObject
(
response
,
Map
.
class
));
map
.
put
(
"elapsedTime"
,
elapsedTime
);
// 插入测试报告
SceneTestcaseReport
sceneTestcaseReport
=
new
SceneTestcaseReport
();
...
...
@@ -155,6 +181,7 @@ public class SceneTestcaseServiceImpl extends ServiceImpl<SceneTestcaseMapper, S
sceneTestcaseReport
.
setSequence
(
sceneTestcase
.
getSequence
());
sceneTestcaseReport
.
setInterfaceUrl
(
anInterface
.
getUrl
());
sceneTestcaseReport
.
setInterfaceName
(
anInterface
.
getName
());
sceneTestcaseReport
.
setTestcaseName
(
sceneTestcase
.
getName
());
sceneTestcaseReport
.
setUrl
(
url
);
sceneTestcaseReport
.
setHeaders
(
JSON
.
toJSONString
(
headersMap
));
sceneTestcaseReport
.
setParameters
(
JSON
.
toJSONString
(
parameterMap
));
...
...
@@ -171,7 +198,10 @@ public class SceneTestcaseServiceImpl extends ServiceImpl<SceneTestcaseMapper, S
sceneTestcaseReport
.
setNamespace
(
namespace
);
log
.
info
(
"保存测试报告:{}"
,
sceneTestcaseReport
);
sceneTestcaseReportService
.
save
(
sceneTestcaseReport
);
return
JSON
.
toJSONString
(
map
);
Map
<
String
,
Object
>
resultMap
=
new
HashMap
<>();
resultMap
.
put
(
"report"
,
reportMap
);
resultMap
.
put
(
"extract"
,
extractMap
);
return
resultMap
;
}
}
src/main/java/cn/qg/holmes/service/gitlab/PipelineService.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
service
.
gitlab
;
import
cn.qg.holmes.entity.gitlab.Pipeline
;
import
com.baomidou.mybatisplus.extension.service.IService
;
public
interface
PipelineService
extends
IService
<
Pipeline
>
{
void
buildPipelineJob
(
String
gitlabData
);
}
src/main/java/cn/qg/holmes/service/gitlab/impl/PipelineServiceImpl.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
service
.
gitlab
.
impl
;
import
cn.qg.holmes.entity.gitlab.Pipeline
;
import
cn.qg.holmes.mapper.gitlab.PipelineMapper
;
import
cn.qg.holmes.service.gitlab.PipelineService
;
import
cn.qg.holmes.service.jira.DingRobotService
;
import
cn.qg.holmes.utils.DingdingUtils
;
import
cn.qg.holmes.utils.JenkinsService
;
import
com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.jayway.jsonpath.JsonPath
;
import
lombok.extern.slf4j.Slf4j
;
import
org.joda.time.DateTime
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.text.SimpleDateFormat
;
@Slf4j
@Service
public
class
PipelineServiceImpl
extends
ServiceImpl
<
PipelineMapper
,
Pipeline
>
implements
PipelineService
{
@Autowired
PipelineMapper
pipelineMapper
;
@Autowired
JenkinsService
jenkinsService
;
@Autowired
DingRobotService
dingRobotService
;
/**
* 构建pipeline
* @param gitlabData gitlab发送过来的推送事件
*/
@Override
public
void
buildPipelineJob
(
String
gitlabData
)
{
SimpleDateFormat
simpleDateFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
String
projectName
=
JsonPath
.
read
(
gitlabData
,
"$.project.name"
);
String
branch
=
JsonPath
.
read
(
gitlabData
,
"$.ref"
).
toString
().
substring
(
11
);
Integer
totalCommitCount
=
JsonPath
.
read
(
gitlabData
,
"$.total_commits_count"
);
if
(
totalCommitCount
.
equals
(
0
))
{
return
;
}
String
message
=
JsonPath
.
read
(
gitlabData
,
"$.commits[-1].message"
);
String
author
=
JsonPath
.
read
(
gitlabData
,
"$.user_username"
);
// push event给过来的日期为带T的,需要进行转换
String
commitDate
=
simpleDateFormat
.
format
(
DateTime
.
parse
(
JsonPath
.
read
(
gitlabData
,
"$.commits[-1].timestamp"
)).
toDate
());
QueryWrapper
<
Pipeline
>
pipelineQueryWrapper
=
new
QueryWrapper
<>();
pipelineQueryWrapper
.
eq
(
"service_name"
,
projectName
);
pipelineQueryWrapper
.
eq
(
"service_branch"
,
branch
);
Pipeline
pipeline
=
pipelineMapper
.
selectOne
(
pipelineQueryWrapper
);
if
(
pipeline
!=
null
)
{
if
(
pipeline
.
getEnable
()
==
1
)
{
log
.
info
(
"pipeline中找到对应项目,且项目是启动状态,开始构建:{}"
,
pipeline
.
toString
());
Integer
buildNum
=
jenkinsService
.
buildJenkinsJob
(
pipeline
.
getServiceType
(),
projectName
,
branch
,
pipeline
.
getNamespace
());
String
markdown
=
DingdingUtils
.
buildPipelineMarkdownMsg
(
projectName
,
branch
,
pipeline
.
getServiceType
(),
author
,
message
,
commitDate
,
pipeline
.
getNamespace
(),
buildNum
.
toString
());
DingdingUtils
.
sendToDingding
(
markdown
,
dingRobotService
.
getById
(
pipeline
.
getDingRobotId
()).
getDingUrl
());
}
else
{
log
.
info
(
"pipeline中找到项目,但是项目状态为不启用,因此不构建!"
);
}
}
else
{
log
.
info
(
"pipeline中未找到该项目相关信息,不触发自动构建!"
);
}
}
}
src/main/java/cn/qg/holmes/service/jira/JiraIssueService.java
View file @
aa5d6cc8
...
...
@@ -14,6 +14,6 @@ public interface JiraIssueService {
Integer
calculateBugFixTime
(
DateTime
startDate
,
DateTime
endDate
);
Issue
getJiraIssueByKey
(
String
key
)
throws
Exception
;
Issue
getJiraIssueByKey
(
String
key
);
}
src/main/java/cn/qg/holmes/service/jira/impl/DingRobotServiceImpl.java
View file @
aa5d6cc8
...
...
@@ -31,7 +31,12 @@ public class DingRobotServiceImpl extends ServiceImpl<DingRobotMapper, DingRobot
String
webhookEvent
=
JsonPath
.
read
(
jiraData
,
"$.webhookEvent"
);
if
(
StringUtils
.
equals
(
webhookEvent
,
"jira:issue_created"
))
{
String
creator
=
JsonPath
.
read
(
jiraData
,
"$.issue.fields.creator.displayName"
);
String
assignee
=
JsonPath
.
read
(
jiraData
,
"$.issue.fields.assignee.displayName"
);
String
assignee
=
""
;
if
(
JsonPath
.
read
(
jiraData
,
"$.issue.fields.assignee"
)
==
null
)
{
assignee
=
"未分配"
;
}
else
{
assignee
=
JsonPath
.
read
(
jiraData
,
"$.issue.fields.assignee.displayName"
);
}
String
key
=
JsonPath
.
read
(
jiraData
,
"$.issue.key"
);
String
summary
=
JsonPath
.
read
(
jiraData
,
"$.issue.fields.summary"
);
String
priority
=
JsonPath
.
read
(
jiraData
,
"$.issue.fields.priority.name"
);
...
...
@@ -45,18 +50,21 @@ public class DingRobotServiceImpl extends ServiceImpl<DingRobotMapper, DingRobot
break
;
}
}
// 首次提交的BUG放入bug池子
JiraBugPool
jiraBugPool
=
new
JiraBugPool
();
jiraBugPool
.
setKey
(
key
);
jiraBugPool
.
setSummary
(
summary
);
jiraBugPool
.
setPriority
(
priority
);
jiraBugPool
.
setReporter
(
creator
);
jiraBugPool
.
setAssignee
(
assignee
);
jiraBugPool
.
setUrl
(
"http://jira2.quantgroup.cn/browse/"
+
key
);
jiraBugPool
.
setDingUrl
(
robotUrl
);
jiraBugPoolService
.
save
(
jiraBugPool
);
// 只有创建了dingRobot的项目的BUG才会被放到BUG池子里
if
(
robotUrl
!=
null
)
{
// 首次提交的BUG放入bug池子
JiraBugPool
jiraBugPool
=
new
JiraBugPool
();
jiraBugPool
.
setKey
(
key
);
jiraBugPool
.
setSummary
(
summary
);
jiraBugPool
.
setPriority
(
priority
);
jiraBugPool
.
setReporter
(
creator
);
jiraBugPool
.
setAssignee
(
assignee
);
jiraBugPool
.
setUrl
(
"http://jira2.quantgroup.cn/browse/"
+
key
);
jiraBugPool
.
setDingUrl
(
robotUrl
);
jiraBugPoolService
.
save
(
jiraBugPool
);
}
if
(
robotUrl
!=
null
)
{
String
markdownMsg
=
DingdingUtils
.
buildMarkdownMsg
(
key
,
summary
,
creator
,
assignee
,
priority
,
module
);
String
markdownMsg
=
DingdingUtils
.
build
BugCommit
MarkdownMsg
(
key
,
summary
,
creator
,
assignee
,
priority
,
module
);
return
DingdingUtils
.
sendToDingding
(
markdownMsg
,
robotUrl
);
}
}
...
...
src/main/java/cn/qg/holmes/service/jira/impl/JiraIssueServiceImpl.java
View file @
aa5d6cc8
...
...
@@ -76,8 +76,14 @@ public class JiraIssueServiceImpl implements JiraIssueService {
}
@Override
public
Issue
getJiraIssueByKey
(
String
key
)
throws
Exception
{
return
jiraRestClient
.
getIssueClient
().
getIssue
(
key
).
get
();
public
Issue
getJiraIssueByKey
(
String
key
)
{
try
{
Issue
issue
=
jiraRestClient
.
getIssueClient
().
getIssue
(
key
).
get
();
return
issue
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
...
...
src/main/java/cn/qg/holmes/task/jira/JiraToDingding.java
View file @
aa5d6cc8
...
...
@@ -13,7 +13,6 @@ import org.springframework.beans.factory.annotation.Value;
import
org.springframework.scheduling.annotation.Scheduled
;
import
org.springframework.stereotype.Component
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
...
...
@@ -55,7 +54,7 @@ public class JiraToDingding {
* bug池里BUG循环
* @throws Exception
*/
@Scheduled
(
cron
=
"0 0 10-20 ? *
2-6
"
)
@Scheduled
(
cron
=
"0 0 10-20 ? *
MON-FRI
"
)
public
void
cycleJiraBugPool
()
throws
Exception
{
if
(
taskDebug
.
equals
(
"true"
))
{
log
.
info
(
"开始执行jira bug pool定时任务!"
);
...
...
@@ -64,22 +63,26 @@ public class JiraToDingding {
List
<
JiraBugPool
>
jiraBugPoolList
=
jiraBugPoolService
.
list
(
jiraBugPoolQueryWrapper
);
for
(
JiraBugPool
jiraBugPool:
jiraBugPoolList
)
{
Issue
issue
=
jiraIssueService
.
getJiraIssueByKey
(
jiraBugPool
.
getKey
());
String
resolveResult
=
issue
.
getStatus
().
getName
();
// 如果已解决或已关闭,仅修改状态
if
(
resolveResult
.
equals
(
"已解决"
)
||
resolveResult
.
equals
(
"关闭"
))
{
jiraBugPool
.
setEnable
(
0
);
// 更新状态
jiraBugPoolService
.
saveOrUpdate
(
jiraBugPool
);
}
else
{
DateTime
startDate
=
issue
.
getCreationDate
();
DateTime
curDate
=
new
DateTime
();
int
duration
=
jiraIssueService
.
calculateBugFixTime
(
startDate
,
curDate
);
log
.
info
(
"{} BUG持续时间:{}小时"
,
issue
.
getKey
(),
duration
);
// DingdingUtils.sendToDingding(DingdingUtils.buildBugFixRemindMsg(issue), jiraBugPool.getDingUrl());
// 如果已超过4个小时,则发送钉钉通知
if
(
duration
>=
4
)
{
DingdingUtils
.
sendToDingding
(
DingdingUtils
.
buildBugFixRemindMsg
(
issue
,
duration
),
"https://oapi.dingtalk.com/robot/send?access_token=835663338d638e40daaf3ab358af741ef0680a826a962c91bedc53b149d85ee1"
);
if
(
issue
!=
null
)
{
String
resolveResult
=
issue
.
getStatus
().
getName
();
// 如果已解决或已关闭,仅修改状态
if
(
resolveResult
.
equals
(
"已解决"
)
||
resolveResult
.
equals
(
"关闭"
))
{
jiraBugPool
.
setEnable
(
0
);
// 更新状态
jiraBugPoolService
.
saveOrUpdate
(
jiraBugPool
);
}
else
{
DateTime
startDate
=
issue
.
getCreationDate
();
DateTime
curDate
=
new
DateTime
();
int
duration
=
jiraIssueService
.
calculateBugFixTime
(
startDate
,
curDate
);
log
.
info
(
"{} BUG持续时间:{}小时"
,
issue
.
getKey
(),
duration
);
// 如果已超过4个小时,则发送钉钉通知
if
(
duration
>=
4
)
{
DingdingUtils
.
sendToDingding
(
DingdingUtils
.
buildBugFixRemindMsg
(
issue
,
duration
),
jiraBugPool
.
getDingUrl
());
}
}
}
else
{
log
.
info
(
"JIRA上未找到该issue,将BUG: {} 置为无效"
,
jiraBugPool
.
getKey
());
jiraBugPool
.
setEnable
(
0
);
}
}
}
...
...
src/main/java/cn/qg/holmes/utils/DingdingUtils.java
View file @
aa5d6cc8
This diff is collapsed.
Click to expand it.
src/main/java/cn/qg/holmes/utils/GitlabService.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
utils
;
import
org.gitlab.api.GitlabAPI
;
import
org.gitlab.api.models.GitlabBranch
;
import
org.gitlab.api.models.GitlabProject
;
import
org.springframework.stereotype.Component
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
public
class
GitlabService
{
private
static
final
String
URL
=
"http://git.quantgroup.cn/"
;
private
static
final
String
TOKEN
=
"owKJZwenxNaypTAz4Zcd"
;
private
GitlabAPI
gitlabAPI
;
public
GitlabService
()
{
try
{
gitlabAPI
=
GitlabAPI
.
connect
(
URL
,
TOKEN
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
/**
* 获取所有的项目
* @return
*/
public
List
<
Map
<
String
,
Object
>>
getProjectList
()
{
List
<
GitlabProject
>
gitlabProjectList
=
gitlabAPI
.
getProjects
();
List
<
Map
<
String
,
Object
>>
projectMapList
=
new
ArrayList
<>();
for
(
GitlabProject
gitlabProject:
gitlabProjectList
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
map
.
put
(
"id"
,
gitlabProject
.
getId
());
map
.
put
(
"name"
,
gitlabProject
.
getName
());
projectMapList
.
add
(
map
);
}
return
projectMapList
;
}
public
List
<
String
>
getBranchesByProjectName
(
String
projectName
)
{
List
<
Map
<
String
,
Object
>>
projectList
=
getProjectList
();
Integer
projectId
=
null
;
for
(
Map
<
String
,
Object
>
map:
projectList
)
{
if
(
map
.
get
(
"name"
).
toString
().
equals
(
projectName
))
{
projectId
=
(
Integer
)
map
.
get
(
"id"
);
}
}
List
<
GitlabBranch
>
gitlabBranchList
=
gitlabAPI
.
getBranches
(
projectId
);
List
<
String
>
branches
=
new
ArrayList
<>();
for
(
GitlabBranch
gitlabBranch:
gitlabBranchList
)
{
branches
.
add
(
gitlabBranch
.
getName
());
}
return
branches
;
}
public
static
void
main
(
String
[]
args
)
{
GitlabService
gitlabService
=
new
GitlabService
();
List
<
String
>
branches
=
gitlabService
.
getBranchesByProjectName
(
"holmes"
);
System
.
out
.
println
(
branches
);
}
}
src/main/java/cn/qg/holmes/utils/JenkinsService.java
0 → 100644
View file @
aa5d6cc8
package
cn
.
qg
.
holmes
.
utils
;
import
com.offbytwo.jenkins.JenkinsServer
;
import
com.offbytwo.jenkins.client.JenkinsHttpClient
;
import
com.offbytwo.jenkins.model.Build
;
import
com.offbytwo.jenkins.model.Job
;
import
com.offbytwo.jenkins.model.JobWithDetails
;
import
org.springframework.stereotype.Component
;
import
java.io.IOException
;
import
java.net.URI
;
import
java.net.URISyntaxException
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* Jenkins 相关操作工具类
* @author libo
*/
@Component
public
class
JenkinsService
{
// Jenkins 对象
private
JenkinsServer
jenkinsServer
;
// http 客户端对象
private
JenkinsHttpClient
jenkinsHttpClient
;
// 连接 Jenkins 需要设置的信息
static
final
String
JENKINS_URL
=
"http://172.29.1.15:8080/"
;
static
final
String
JENKINS_USERNAME
=
"qahome"
;
static
final
String
JENKINS_PASSWORD
=
"Quantgroup123"
;
/**
* 构造方法中调用连接 Jenkins 方法
*/
public
JenkinsService
()
{
// 连接 Jenkins
try
{
jenkinsServer
=
new
JenkinsServer
(
new
URI
(
JENKINS_URL
),
JENKINS_USERNAME
,
JENKINS_PASSWORD
);
}
catch
(
URISyntaxException
e
)
{
e
.
printStackTrace
();
}
}
/**
* 构建jenkins job
* @param type 服务类型:java/node/ui
* @param project 项目名
* @param branch 分支名
* @param namespace 部署的环境
* @return
*/
public
int
buildJenkinsJob
(
String
type
,
String
project
,
String
branch
,
String
namespace
)
{
Map
<
String
,
String
>
buildParams
=
new
HashMap
<>();
buildParams
.
put
(
"GIT_REPO"
,
project
);
buildParams
.
put
(
"BRANCH_NAME"
,
branch
);
buildParams
.
put
(
"DEPLOY"
,
"true"
);
buildParams
.
put
(
"NAMESPACE"
,
namespace
);
try
{
jenkinsServer
.
getJob
(
"tke-"
+
type
).
build
(
buildParams
);
Build
build
=
jenkinsServer
.
getJob
(
"tke-"
+
type
).
getLastBuild
();
return
build
.
getNumber
()
+
1
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
return
0
;
}
}
/**
* 根据job名称获取job信息
*/
public
JobWithDetails
getJobInfoByName
(
String
jobName
)
{
try
{
JobWithDetails
job
=
jenkinsServer
.
getJob
(
jobName
);
return
job
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
* 获取job列表
* @return
*/
public
List
<
Map
<
String
,
String
>>
getJobList
()
{
try
{
Map
<
String
,
Job
>
jobs
=
jenkinsServer
.
getJobs
();
List
<
Map
<
String
,
String
>>
jobList
=
new
ArrayList
<>();
for
(
Job
job:
jobs
.
values
()){
Map
<
String
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
"value"
,
job
.
getName
());
map
.
put
(
"label"
,
job
.
getName
());
jobList
.
add
(
map
);
}
return
jobList
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
* 获取Job Build列表
*/
public
List
<
Build
>
getJobBuildList
(
String
jobName
,
Integer
num
)
{
try
{
// 获取 Job 信息
JobWithDetails
job
=
jenkinsServer
.
getJob
(
jobName
);
// 获取全部 Build 信息
Build
lastBuild
=
job
.
getLastBuild
();
int
lastBuildNumber
=
lastBuild
.
getNumber
();
List
<
Build
>
buildList
=
new
ArrayList
<>();
for
(
int
i
=
lastBuildNumber
;
i
>
lastBuildNumber
-
num
;
i
--)
{
Build
tempBuild
=
job
.
getBuildByNumber
(
i
);
if
(
tempBuild
==
null
)
{
return
buildList
;
}
else
{
buildList
.
add
(
job
.
getBuildByNumber
(
i
));
}
}
return
buildList
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
* 根据参数获取对应的build
*/
public
List
<
Build
>
getJobBuildList
(
String
jobName
,
Integer
num
,
String
project
)
{
try
{
// 获取 Job 信息
JobWithDetails
job
=
jenkinsServer
.
getJob
(
jobName
);
int
lastBuildNumber
=
job
.
getLastBuild
().
getNumber
();
List
<
Build
>
buildList
=
new
ArrayList
<>();
int
caculator
=
0
;
while
(
buildList
.
size
()
!=
num
)
{
Build
build
=
job
.
getBuildByNumber
(
lastBuildNumber
-
caculator
);
if
(
build
==
null
)
{
return
buildList
;
}
if
(
build
.
details
().
getParameters
().
get
(
"GIT_REPO"
).
equals
(
project
))
{
buildList
.
add
(
build
);
}
caculator
+=
1
;
}
return
buildList
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
public
static
void
main
(
String
[]
args
)
throws
IOException
{
JenkinsService
jenkinsApi
=
new
JenkinsService
();
// List<Build> buildList = jenkinsApi.getJobBuildList("tke-java", 1, "kdsp");
// List<String> userList = new ArrayList<>();
// for (Build build: buildList) {
// System.out.println(build.details().getParameters().get("BRANCH_NAME"));
// System.out.println(build.details().getParameters().get("NAMESPACE"));
// System.out.println(build.details().getCauses().get(0).getUserName());
// userList.add(build.details().getCauses().get(0).getUserName());
// BuildResult buildResult = build.details().getResult();
// System.out.println(buildResult);
// }
// System.out.println(userList.size());
System
.
out
.
println
(
jenkinsApi
.
buildJenkinsJob
(
"ui"
,
"qa-platform-ui"
,
"xiaotong"
,
"fe"
));
}
}
src/main/resources/mapper/auto/SceneTestcaseMapper.xml
View file @
aa5d6cc8
...
...
@@ -3,7 +3,12 @@
<mapper
namespace=
"cn.qg.holmes.mapper.auto.SceneTestcaseMapper"
>
<select
id=
"getSceneTestcaseListBySceneId"
resultType=
"cn.qg.holmes.entity.auto.SceneTestcase"
>
select stc.*,it.`name`,sc.`name`,am.`name` from `scene_testcase` as stc
select stc.*,
it.`name` as interfaceName,
it.`url` as interfaceUrl,
sc.`name` as sceneName,
am.`name` as moduleName
from `scene_testcase` as stc
INNER JOIN `interface` as it ON stc.`interface_id` = it.`id`
INNER JOIN `scene` as sc ON stc.`scene_id` = sc.`id`
INNER JOIN `auto_module` as am ON it.`module_id` = am.id
...
...
src/main/resources/mapper/auto/TestcaseMapper.xml
View file @
aa5d6cc8
...
...
@@ -3,7 +3,10 @@
<mapper
namespace=
"cn.qg.holmes.mapper.auto.TestcaseMapper"
>
<select
id=
"getTestcaseList"
resultType=
"cn.qg.holmes.entity.auto.Testcase"
>
SELECT tc.*, am.`name` as moduleName, it.`name` as interfaceName
SELECT tc.*,
am.`name` as moduleName,
it.`name` as interfaceName,
it.`url` as interfaceUrl
FROM `testcase` as tc
INNER JOIN `auto_module` as am ON tc.`module_id` = am.`id`
INNER JOIN `interface` as it ON tc.`interface_id` = it.`id`
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment