반응형
재직중인 회사에서 자동화를 위해서 Spring-batch와 Jenkins를 이용하여 무언가를 체크하는 로직을 만들었고 요청이 들어올때마다 실행해주고 있었습니다. 하지만 이것도 불편하다!! 웹에서 버튼을 눌렀을 때 Jenkins의 Item을 실행해보자!
Jenkins Token 발급
먼저 Jenkins에서 Token을 발급받아야만 Jenkins API를 사용할 수 있습니다. Token을 발급받아보겠습니다. 먼저 People에 들어가 발급받는 유저를 선택하고 Configure로 진입합니다.
구성화면에 진입한 후 Add New Token 버튼을 클릭합니다.
토큰 명을 입력하고 Generate 버튼을 클릭합니다.
생성된 토큰을 저장합니다.
Code 작성
Jenkins와 통실할 클래스를 생성합니다.
application.yaml
jenkins:
url: localhost:8080
user: limyongtae
token: 148ca24cccc51e1dddde3affffafaad9e5
jenkins의 정보를 입력합니다.
- url : jenkins의 url
- user : 이전 단락에서 토큰을 발급받은 user
- token : 이전 단락에서 저장한 토큰
JenkinsProperties
application.yaml에서 설정한 jenkins properties 클래스입니다.
@Configuration
@ConfigurationProperties(prefix = "jenkins")
@Getter @Setter
public class JenkinsProperties {
private String url;
private String user;
private String token;
}
JenkinsUrl
먼저 상수 열거형(enum)에 Jenkins로 배포할 url 정보를 선언합니다.
@Getter
public enum JenkinsUrl {
BUILD("/build"),
BUILD_WITH_PARAMS("/buildWithParameters"),
JENKINS_URL_PATTERN("http://%s/job/%s/%s");
private String url;
JenkinsUrl(String url) {
this.url = url;
}
}
JenkinsParamCollection
Jenkins 배포 시 parameter를 설정할 경우 사용되는 일급 컬렉션입니다.
public class JenkinsParamCollection {
private final MultiValueMap<String, String> postParams;
public JenkinsParamCollection(MultiValueMap<String, String> postParams) {
this.postParams = postParams;
}
public void put(String key, String value) {
postParams.set(key, value);
}
public void put(String key, List<String> values) {
postParams.put(key, values);
}
public List<String> get(String key) {
return postParams.get(key);
}
}
여기서 주의깊게 살펴보실 내용은 일반 Map을 쓰지않고 MultiValueMap을 사용하였습니다. 이유는 파라미터로 동일한 Key에 다른 Value값을 주입할 수 있도록 하기 위해서입니다.
RestClient
API 통신 Client입니다.
@Component
@RequiredArgsConstructor
public class RestClient {
private final RestTemplate restTemplate;
private final String HEADER_BASIC = "Basic ";
private final String AUTHORIZATION = "Authorization";
public <T> ResponseEntity<T> get(final String url, final Class<T> responseType) {
return restTemplate.getForEntity(url, responseType);
}
public <T> ResponseEntity<T> post(final String url, Object request, final Class<T> responseType) {
return restTemplate.postForEntity(url, request, responseType);
}
public void put(final String url, final Object request) {
restTemplate.put(url, request);
}
public void delete(final String url) {
restTemplate.delete(url);
}
public void addHeader(String username, String token) {
String authHeaderValue = HEADER_BASIC + Base64.getEncoder().encodeToString((username + ":" + token).getBytes(StandardCharsets.UTF_8));
restTemplate.getInterceptors().add((request, body, execution) -> {
HttpHeaders headers = request.getHeaders();
headers.set(AUTHORIZATION, authHeaderValue);
return execution.execute(request, body);
});
}
}
JenkinsClient
Jenkins와 실제로 통신하는 Client입니다.
public class JenkinsClient {
private final JenkinsProperties properties;
private final RestClient restClient;
private String endpoint;
private JenkinsParamCollection jenkinsParamCollection;
public JenkinsClient(JenkinsProperties properties, RestClient restClient) {
this.properties = properties;
this.restClient = restClient;
this.endpoint = JenkinsUrl.BUILD.getUrl();
this.jenkinsParamCollection = new JenkinsParamCollection(new LinkedMultiValueMap<>());
setJenkinsConfig();
}
public void build(String jobName) {
String url = generateUrl(jobName);
this.restClient.post(url, this.jenkinsParamCollection, String.class);
}
public void setParameters(Map<String, String> jobParameters) {
if (jobParameters != null) {
jobParameters.forEach(this.jenkinsParamCollection::put);
}
this.endpoint = JenkinsUrl.BUILD_WITH_PARAMS.getUrl();
}
private void setJenkinsConfig() {
addHeader();
}
private void addHeader() {
this.restClient.addHeader(this.properties.getUser(), this.properties.getToken());
}
private String generateUrl(String jobName) {
return String.format(JenkinsUrl.JENKINS_URL_PATTERN.getUrl(), this.properties.getUrl(), jobName, this.endpoint);
}
}
Header에 인증 정보를 넣고 요청하는 JenkinsClient입니다.
반응형