재귀함수란 자기자신을 호출하는 함수
Jenkins API를 사용하는데.. 개불편함
현재 구조는 아래와 같음
======================================================================================================
0. 최상위폴더
1. 폴더
2.폴더
3.잡
4.잡
5.폴더
6.폴더
7.폴더
8.잡
9.잡
10.잡
11.잡
======================================================================================================
이거를 한번에 가져오고싶은데, jenkins에서는 한번에 한댑스의 목록만가져올수가있음
말그대로 한번호출하면 1,5,11
1. 폴더에서 한번 들어가면 2, 4
5. 폴더에서 한번 들어가면 6, 10
이런식임..
폴더일 경우에는 하위에 폴더나 잡이 또 생길수 있고,잡일경우에는 더이상 하위에 생길수가 없음
생각해보면 모든 폴더에 적용이 되며 아래의 로직을 따라감
1. 목록을 가져온다
2. 가져온 목록에서 폴더가 있는지 확인하다
3. 폴더가 있다면 해당 폴더명으로 목록을 가져온다
4. 3에서 가져온 목록에 폴더가 있다면 해당 폴더 명으로 목록을 가져온다.
5. 폴더밑에 아무것도 없거나, 폴더가 없을떄까지 진행한다.
젠킨스 API는 아래와 같은 구조로 목록을 제공해줌
JenkinsURL/job/폴더명/api/json
ex) http://sungchul.jenkins.com/job/0. 최상위폴더/api/json
이렇게 조회하게되면 1.폴더 , 5.폴더 , 11. 잡이 리턴됨
여기서 하위를 조회하려면 상위의 URL 에다가 하위의 폴더명도 붙어야댐
JenkinsURL/job/폴더명/job/하위폴더명/api/json
ex) http://sungchul.jenkins.com/job/0. 최상위폴더/job/1.폴더/api/json
이렇게 하면 이제 1. 폴더 밑에 있는 2.폴더, 4. 잡이 조회됨
이것을 반복하면서 트리구조로 목록을 가져오려고 함
[ 실제 작성 코드]
재귀함수를 사용하여서, 하위목록이 있을 경우 계속 호출하게 작성하였음
VO의 생성자는 Object 로 넘어온 값을 파싱하여 각각에 맞는 필드에 넣어주도록 수정하였음
Serivce의 getJenkinsListAPI 메소드에서는 재귀함수로 호출해서 받아오는 값을 add 하지않고 set 으로 변경하도록 하였음
add를 하게되면 본인 하위에 본인이 또 추가되서 두개씩 출력되는 상황이 발생함 (무한루프는안돌고 두번씩돔)
그래서 조회된 값으로 변경하도록 수정하였음
## 컨트롤러
====================================================================================================
@ApiOperation(value = "Jenkins 목록 조회",notes = "프로젝트에 포함되어 있는 Jenkins 목록 조회")
@RequestMapping(value = "/jenkins/{projectId}", method = RequestMethod.GET)
public ResponseEntity<ApiResponseEntity> getJenkinsList(@PathVariable("projectId") String projectId ) {
List<NewJenkinsParamVO> jenkins = newJenkinsService.getJenkinsList(projectId);
String statusMsg = DbMessageManager.getMessage("I0001", "ko");
ApiResponseEntity message = new ApiResponseEntity(statusMsg, jenkins, null, null);
return new ResponseEntity<ApiResponseEntity>(message, HttpStatus.OK);
}
====================================================================================================
## 서비스
전달받은 프로젝트 id로, DB에 저장되어 있는 Jenkins 목록의 uri를 생성하여 getJenkinsListAPI() 메소드를 호출 한 후,
리턴받은 값을 리스트에 담아서 리턴
====================================================================================================
/**
* 프로젝트 상세 조회 - Jenkins 전체 목록 조회
* @param projectId
* @return List<NewJenkinsParamVO>
*/
public List<NewJenkinsParamVO> getJenkinsList(String projectId) {
List<NewJenkinsParamVO> result = new ArrayList<>();
//지금은 테스트용으로 배열에서 사용중,
String topJenkinsList[] = {"kscJenkins267" , "kscJenkin260" , "kscJenkins255", "kscJenkinsJobTop254"};
String uri="";
for(int i=0;i<topJenkinsList.length;i++) {
uri = jenkinsUrl + "/job/" + topJenkinsList[i];
NewJenkinsParamVO newJenkinsParamVO = getJenkinsListAPI(uri);
result.add(newJenkinsParamVO);
}
System.out.println(result);
return result;
}
====================================================================================================
전달받은 uri를 기준으로 하위목록 전체를 조회하여 트리구조로 리턴
====================================================================================================
/**
* 프로젝트 상세조회 - 최상단 job, folder 기준으로 하위 목록 job, folder 조회
* @param uri
* @return List<NewJenkinsParamVO>
*/
public NewJenkinsParamVO getJenkinsListAPI(String uri) {
String params="";
ResponseEntity<String> result = null;
result = restService.getRestApiForJson(uri+"/api/json", makeHttpHeader(), params);
NewJenkinsParamVO newJenkinsParamVO = getJenkinsProject(result.getBody());
if(newJenkinsParamVO.getFolders().size()>0) {
for(int i=0;i < newJenkinsParamVO.getFolders().size();i++) {
//newJenkinsFolderParamVO.getNewJenkinsFolderList().add(getJenkinsListAPI(newJenkinsFolderParamVO.getNewJenkinsFolderList().get(i).getJenkinsFolderName(),uri+"/job/"+newJenkinsFolderParamVO.getNewJenkinsFolderList().get(i).getJenkinsFolderName()));
NewJenkinsParamVO newJenkinsFolderParamVO2 = new NewJenkinsParamVO();
newJenkinsFolderParamVO2 = getJenkinsListAPI(uri+"/job/"+newJenkinsParamVO.getFolders().get(i).getJenkinsFolderName());
//newJenkinsFolderParamVO.getNewJenkinsFolderList().get(i).getNewJenkinsFolderList().add(newJenkinsFolderParamVO2);
newJenkinsParamVO.getFolders().set(i, newJenkinsFolderParamVO2);
}
}
return newJenkinsParamVO;
}
====================================================================================================
## 맵퍼
## VO
NewJenkinsParamVO , 젠킨스에서 전달해준 값을을 화면으로 보내는데 사용하는 VO
Jenkins 에서 보내준 값을 파싱하여서 저장하도록 작성함
====================================================================================================
package com.kt.dspace.portal.project.jenkins.test;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(value = "New 잰킨스 VO", description = "New 잰킨스 VO")
public class NewJenkinsParamVO {
@ApiModelProperty(name = "jenkinsFolderName", value = "folder명", dataType = "String")
public String jenkinsFolderName;
@ApiModelProperty(name = "jenkinsNmJobName", value = "job명", dataType = "String")
public String jenkinsNmJobName;
@ApiModelProperty(name = "flagClass", value = "folder , job 구분", dataType = "String")
public String flagClass;
@ApiModelProperty(name = "url", value = "jenkins url", dataType = "String")
public String url;
@ApiModelProperty(name = "newJenkinsFolderList", value = "folder 목록", dataType = "String")
public ArrayList<NewJenkinsParamVO> folders;
@ApiModelProperty(name = "newJenkinsJobList", value = "job 목록", dataType = "String")
public ArrayList<NewJenkinsParamVO> jobs;
public NewJenkinsParamVO() {
super();
folders=new ArrayList<>();
jobs=new ArrayList<>();
}
public NewJenkinsParamVO(JSONObject object) {
folders=new ArrayList<>();
jobs=new ArrayList<>();
if(object.has("_class")) {
if(object.get("_class") == JSONObject.NULL) {
this.flagClass = "";
} else {
String tempFlagClass[] = object.get("_class").toString().split("\\.");
this.flagClass = tempFlagClass[tempFlagClass.length-1];
if(this.flagClass.contains("Folder")) {
this.jenkinsFolderName = object.getString("name");
}else {
this.jenkinsNmJobName = object.getString("name");
}
}
}
if(object.has("url")) {
if(object.get("url") == JSONObject.NULL) {
this.url = "";
} else {
this.url = object.getString("url");
}
}
try {
if(object.has("jobs")) {
//하위 jobs 존재여부 확인
if(object.get("jobs") != JSONObject.NULL) {
JSONArray jsonArray = (JSONArray) object.get("jobs");
for(int i=0;i<jsonArray.length();i++) {
if(((String) jsonArray.getJSONObject(i).get("_class")).contains("Folder")) {
NewJenkinsParamVO tempNewJenkinsVO = new NewJenkinsParamVO(jsonArray.getJSONObject(i));
folders.add(tempNewJenkinsVO);
}else {
NewJenkinsParamVO tempNewJenkinsJobVO = new NewJenkinsParamVO(jsonArray.getJSONObject(i));
jobs.add(tempNewJenkinsJobVO);
}
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
public String getJenkinsFolderName() {
return jenkinsFolderName;
}
public void setJenkinsFolderName(String jenkinsFolderName) {
this.jenkinsFolderName = jenkinsFolderName;
}
public String getJenkinsNmJobName() {
return jenkinsNmJobName;
}
public void setJenkinsNmJobName(String jenkinsNmJobName) {
this.jenkinsNmJobName = jenkinsNmJobName;
}
public String getFlagClass() {
return flagClass;
}
public void setFlagClass(String flagClass) {
this.flagClass = flagClass;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public ArrayList<NewJenkinsParamVO> getFolders() {
return folders;
}
public void setFolders(ArrayList<NewJenkinsParamVO> folders) {
this.folders = folders;
}
public ArrayList<NewJenkinsParamVO> getJobs() {
return jobs;
}
public void setJobs(ArrayList<NewJenkinsParamVO> jobs) {
this.jobs = jobs;
}
@Override
public String toString() {
return "NewJenkinsParamVO [jenkinsFolderName=" + jenkinsFolderName + ", jenkinsNmJobName=" + jenkinsNmJobName
+ ", flagClass=" + flagClass + ", url=" + url + ", folders=" + folders + ", jobs=" + jobs + "]";
}
}
====================================================================================================