Java tutorial
/* * * Copyright (c) 2015 SERENA Software, Inc. All Rights Reserved. * * This software is proprietary information of SERENA Software, Inc. * Use is subject to license terms. * */ package com.serena.rlc.provider.jenkins.client; import com.serena.rlc.provider.jenkins.domain.BuildInfo; import com.serena.rlc.provider.jenkins.domain.Job; import com.serena.rlc.provider.jenkins.exception.JenkinsClientException; import org.apache.commons.httpclient.HttpStatus; import org.apache.http.*; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.DefaultHttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; import org.apache.commons.lang3.StringUtils; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.message.BasicNameValuePair; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; /** * @author rcook */ @Component public class JenkinsClient { private static final Logger logger = LoggerFactory.getLogger(JenkinsClient.class); public static String DEFAULT_HTTP_CONTENT_TYPE = "application/json"; private String jenkinsUrl; private String jenkinsUsername; private String jenkinsPassword; private int pollSleepTime = 1000; private int maxPollCount = 15; public JenkinsClient() { } public JenkinsClient(String url) { this.jenkinsUrl = url; } public JenkinsClient(String url, String username, String password) { this.jenkinsUrl = url; this.jenkinsUsername = username; this.jenkinsPassword = password; } public String getJenkinsUrl() { return jenkinsUrl; } public void setJenkinsUrl(String url) { this.jenkinsUrl = url; } public String getJenkinsUsername() { return jenkinsUsername; } public void setJenkinsUsername(String username) { this.jenkinsUsername = username; } public String getJenkinsPassword() { return jenkinsPassword; } public void setJenkinsPassword(String password) { this.jenkinsPassword = password; } public int getPollSleepTime() { return pollSleepTime; } public void setPollSleepTime(int pollSleepTime) { this.pollSleepTime = pollSleepTime; } public int getMaxPollCount() { return maxPollCount; } public void setMaxPollCount(int maxPollCount) { this.maxPollCount = maxPollCount; } public void createConnection(String url, String username, String password) { this.jenkinsUrl = url; this.jenkinsUsername = username; this.jenkinsPassword = password; } public void createConnection(String url) { this.jenkinsUrl = url; } public List<Job> getJobs() throws JenkinsClientException { logger.debug("Using Jenkins URL: " + getJenkinsUrl()); logger.debug("Retrieving Jenkins Jobs"); String jobsResponse = processGet(getJenkinsUrl(), "api/json?tree=jobs[name,displayName]"); logger.debug(jobsResponse); List<Job> jobs = Job.parse(jobsResponse); return jobs; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Send a POST and returns the Location header which contains the url to the queued item * * @param jenkinsUrl * @param postPath * @param postData * @return Response body * @throws JenkinsClientException */ public String processBuildPost(String jenkinsUrl, String postPath, String postData) throws JenkinsClientException { String uri = createUrl(jenkinsUrl, postPath); logger.debug("Start executing Jenkins POST request to url=\"{}\" with payload={}", uri); DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost postRequest = new HttpPost(uri); if (getJenkinsUsername() != null && !StringUtils.isEmpty(getJenkinsUsername())) { UsernamePasswordCredentials creds = new UsernamePasswordCredentials(getJenkinsUsername(), getJenkinsPassword()); postRequest.addHeader(BasicScheme.authenticate(creds, "US-ASCII", false)); } postRequest.addHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded"); postRequest.addHeader(HttpHeaders.ACCEPT, "application/json"); String result = ""; List<NameValuePair> params = new ArrayList<>(); params.add(new BasicNameValuePair("json", postData)); try { postRequest.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); HttpResponse response = httpClient.execute(postRequest); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK && response.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { throw createHttpError(response); } result = response.getFirstHeader("Location").getValue(); logger.debug("End executing Jenkins POST request to url=\"{}\" and receive this result={}", uri, result); } catch (IOException e) { logger.error(e.getMessage(), e); throw new JenkinsClientException("Server not available", e); } finally { httpClient.getConnectionManager().shutdown(); } return result; } public BuildInfo startBuild(String jobName, String parameters) throws JenkinsClientException { logger.debug("Start Jenkins Job \"{}\" with parameters: {}", jobName, parameters); //String queueLocation = processBuildPost(this.getJenkinsUrl(), "job/" + jobName + "/build", parameters); String queueLocation = this.processBuildPost(this.getJenkinsUrl(), "job/" + jobName + "/buildWithParameters" + parameters, null); BuildInfo queueCheckResult = null; logger.debug("Checking Queue Location ({})", queueLocation); // Jenkins does not return a build number when a build is started. It returns a URL to the build queue // which is not available immediately. Once it is available and the time int pollCount = 0; while (pollCount < getMaxPollCount()) { try { Thread.sleep(getPollSleepTime()); queueCheckResult = checkBuildQueue(queueLocation, jobName); logger.debug("Queue Result ({})", queueCheckResult); } catch (JenkinsClientException ex) { logger.debug("Error Checking the build queue ({}) - {}", queueLocation, ex.getMessage()); System.out.println( String.format("Error Checking the build queue (%s) - %s", queueLocation, ex.getMessage())); } catch (InterruptedException ex) { //java.util.logging.Logger.getLogger(JenkinsClient.class.getName()).log(Level.SEVERE, null, ex); } if (queueCheckResult != null && queueCheckResult.hasBuildNumber()) { break; } pollCount++; } return queueCheckResult; } private BuildInfo checkBuildQueue(String queueUrl, String jobName) throws JenkinsClientException { BuildInfo result = null; String getResult = processGet(queueUrl, "api/json?tree=url,why,blocked,executable[number,url]"); if (!StringUtils.isEmpty(getResult)) { try { JSONParser parser = new JSONParser(); Object parsedObject = parser.parse(getResult); JSONObject executable = (JSONObject) ((JSONObject) parsedObject).get("executable"); result = new BuildInfo(); result.setName(jobName); result.setQueueUrl(queueUrl); result.setMessage((String) ((JSONObject) parsedObject).get("why")); if (executable != null) { result.setBuildUrl((String) executable.get("url")); result.setBuildNumber((Long) executable.get("number")); } } catch (Exception ex) { System.out.println("EX"); } } return result; } /** * Execute a get request * * @param jenkinsUrl * @param getPath * @return Response body * @throws JenkinsClientException */ public String processGet(String jenkinsUrl, String getPath) throws JenkinsClientException { String uri = createUrl(jenkinsUrl, getPath); logger.debug("Start executing Jenkins GET request to url=\"{}\"", uri); DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet getRequest = new HttpGet(uri); if (getJenkinsUsername() != null && !StringUtils.isEmpty(getJenkinsUsername())) { UsernamePasswordCredentials creds = new UsernamePasswordCredentials(getJenkinsUsername(), getJenkinsPassword()); getRequest.addHeader(BasicScheme.authenticate(creds, "US-ASCII", false)); } getRequest.addHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded"); getRequest.addHeader(HttpHeaders.ACCEPT, "application/json"); String result = ""; try { HttpResponse response = httpClient.execute(getRequest); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { throw createHttpError(response); } BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent()))); StringBuilder sb = new StringBuilder(1024); String output; while ((output = br.readLine()) != null) { sb.append(output); } result = sb.toString(); } catch (IOException e) { logger.error(e.getMessage(), e); throw new JenkinsClientException("Server not available", e); } finally { httpClient.getConnectionManager().shutdown(); } logger.debug("End executing Jenkins GET request to url=\"{}\" and receive this result={}", uri, result); return result; } /** * @param jenkinsUrl * @param path * @return */ public String createUrl(String jenkinsUrl, String path) { String result; // URI uri; if (!jenkinsUrl.endsWith("/")) { jenkinsUrl += "/"; } if (path.startsWith("/")) { path = path.substring(1); } try { //uri = new URI(jenkinsUrl + path); result = (jenkinsUrl + path).replace(" ", "%20"); } catch (Exception e) { result = jenkinsUrl + path; } return result; } private JenkinsClientException createHttpError(HttpResponse response) { String message; try { StatusLine statusLine = response.getStatusLine(); BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); String line; StringBuffer responsePayload = new StringBuffer(); // Read response until the end while ((line = rd.readLine()) != null) { responsePayload.append(line); } message = String.format("request not successful: %d %s. Reason: %s", statusLine.getStatusCode(), HttpStatus.getStatusText(statusLine.getStatusCode()), responsePayload); logger.info(message); if (new Integer(HttpStatus.SC_UNAUTHORIZED).equals(statusLine.getStatusCode())) { return new JenkinsClientException("Invalid credentials provided."); } else if (new Integer(HttpStatus.SC_NOT_FOUND).equals(statusLine.getStatusCode())) { return new JenkinsClientException("Jenkins: Request URL not found."); } else if (new Integer(HttpStatus.SC_BAD_REQUEST).equals(statusLine.getStatusCode())) { return new JenkinsClientException("Jenkins: Bad request. " + responsePayload); } } catch (IOException e) { return new JenkinsClientException("Jenkins: Can't read response"); } return new JenkinsClientException(message); } static public void main(String[] args) throws JenkinsClientException { /* JenkinsClient jc = new JenkinsClient(null, "http://serenadeploy:9090/", "admin", "admin", null); System.out.println("Retrieving Jenkins Projects..."); String projResponse = null; try { projResponse = jc.processGet(null, jc.getJenkinsUrl(), "rest/api/2/project"); } catch (JiraClientException e) { System.out.print(e.toString()); } System.out.println(projResponse); System.out.println("Retrieving Jenkins Issues for projects..."); */ JenkinsClient jc = new JenkinsClient("http://10.31.25.44:8080/jenkins/", "admin", "admin"); //jc.processBuildPost("http://10.31.25.44:8080/jenkins/", "job/Build Job 3/build", "{\"parameter\": []}"); System.out.println(jc.startBuild("Build Job 3", "{\"parameter\": []}")); } }