config.xml which should be used to create
+ * the job.
+ * @throws IOException in case of an error.
*/
- public void createJob(String jobName, String jobXml) throws IOException {
- createJob(null, jobName, jobXml, true);
+ public JenkinsServer createJob(String jobName, String jobXml) throws IOException {
+ return createJob(null, jobName, jobXml, false);
}
/**
* Create a job on the server using the provided xml
- *
- * @return the new job object
- * @throws IOException
+ *
+ * @param jobName name of the job to be created.
+ * @param jobXml the config.xml which should be used to create
+ * the job.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException in case of an error.
*/
- public void createJob(String jobName, String jobXml, Boolean crumbFlag) throws IOException {
- createJob(null, jobName, jobXml, crumbFlag);
+ public JenkinsServer createJob(String jobName, String jobXml, Boolean crumbFlag) throws IOException {
+ return createJob(null, jobName, jobXml, crumbFlag);
}
/**
* Create a job on the server using the provided xml and in the provided
* folder
*
- * @return the new job object
- * @throws IOException
+ * @param folder {@link FolderJob}
+ * @param jobName name of the job to be created.
+ * @param jobXml the config.xml which should be used to create
+ * the job.
+ * @throws IOException in case of an error.
*/
- public void createJob(FolderJob folder, String jobName, String jobXml) throws IOException {
- createJob(folder, jobName, jobXml, true);
+ public JenkinsServer createJob(FolderJob folder, String jobName, String jobXml) throws IOException {
+ return createJob(folder, jobName, jobXml, false);
}
/**
* Create a job on the server using the provided xml and in the provided
* folder
*
- * @return the new job object
- * @throws IOException
+ * @param folder {@link FolderJob}
+ * @param jobName name of the job to be created.
+ * @param jobXml the config.xml which should be used to create
+ * the job.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException in case of an error.
*/
- public void createJob(FolderJob folder, String jobName, String jobXml, Boolean crumbFlag) throws IOException {
- String path = "/";
- if (folder != null) {
- path = folder.getUrl();
- }
- client.post_xml(path + "createItem?name=" + EncodingUtils.encodeParam(jobName), jobXml, crumbFlag);
+ public JenkinsServer createJob(FolderJob folder, String jobName, String jobXml, Boolean crumbFlag)
+ throws IOException {
+ client.post_xml(UrlUtils.toBaseUrl(folder) + "createItem?name=" + EncodingUtils.formParameter(jobName), jobXml, crumbFlag);
+ return this;
}
/**
- * Create a folder on the server (in the root)
+ * Create a view on the server using the provided xml
+ *
+ * @param viewName name of the view to be created.
+ * @param viewXml The configuration for the view.
+ * @throws IOException in case of an error.
+ */
+ public JenkinsServer createView(String viewName, String viewXml) throws IOException {
+ return createView(null, viewName, viewXml, false);
+ }
+
+ /**
+ * Create a view on the server using the provided xml.
*
- * @throws IOException
+ * @param viewName name of the view to be created.
+ * @param viewXml The configuration for the view.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException in case of an error.
+ */
+ public JenkinsServer createView(String viewName, String viewXml, Boolean crumbFlag) throws IOException {
+ return createView(null, viewName, viewXml, crumbFlag);
+ }
+
+ /**
+ * Create a view on the server using the provided xml and in the provided
+ * folder.
+ *
+ * @param folder {@link FolderJob}
+ * @param viewName name of the view to be created.
+ * @param viewXml The configuration for the view.
+ * @throws IOException in case of an error.
*/
- public void createFolder(String jobName) throws IOException {
- createFolder(null, jobName, false);
+ public JenkinsServer createView(FolderJob folder, String viewName, String viewXml) throws IOException {
+ return createView(folder, viewName, viewXml, false);
+ }
+
+ /**
+ * Create a view on the server using the provided xml and in the provided
+ * folder.
+ *
+ * @param folder the folder.
+ * @param viewName the view name.
+ * @param viewXml the view xml.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException in case of an error.
+ */
+ public JenkinsServer createView(FolderJob folder, String viewName, String viewXml, Boolean crumbFlag)
+ throws IOException {
+ client.post_xml(UrlUtils.toBaseUrl(folder) + "createView?name=" + EncodingUtils.formParameter(viewName), viewXml,
+ crumbFlag);
+ return this;
}
/**
* Create a folder on the server (in the root)
- *
- * @throws IOException
+ *
+ * @param folderName name of the folder.
+ * @throws IOException in case of an error.
*/
- public void createFolder(String jobName, Boolean crumbFlag) throws IOException {
- createFolder(null, jobName, crumbFlag);
+ public JenkinsServer createFolder(String folderName) throws IOException {
+ return createFolder(null, folderName, false);
}
/**
- * Create a folder on the server (in the given folder)
+ * Create a folder on the server (in the root)
+ *
+ * @param folderName name of the folder.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException in case of an error.
+ */
+ public JenkinsServer createFolder(String folderName, Boolean crumbFlag) throws IOException {
+ return createFolder(null, folderName, crumbFlag);
+ }
+
+ /**
+ * Create a job on the server (in the given folder)
*
- * @throws IOException
+ * @param folder {@link FolderJob}
+ * @param jobName name of the job.
+ * @throws IOException in case of an error.
*/
- public void createFolder(FolderJob folder, String jobName) throws IOException {
- createFolder(folder, jobName, false);
+ public JenkinsServer createFolder(FolderJob folder, String jobName) throws IOException {
+ return createFolder(folder, jobName, false);
}
/**
- * Create a folder on the server (in the given folder)
+ * Create a job on the server (in the given folder)
*
- * @throws IOException
+ * @param folder {@link FolderJob}
+ * @param jobName name of the job.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException in case of an error.
*/
- public void createFolder(FolderJob folder, String jobName, Boolean crumbFlag) throws IOException {
- String path = "/";
- if (folder != null) {
- path = folder.getUrl();
- }
+ public JenkinsServer createFolder(FolderJob folder, String jobName, Boolean crumbFlag) throws IOException {
// https://gist.github.com/stuart-warren/7786892 was slightly helpful
// here
- ImmutableMaptrue to add crumbIssuer
+ * false otherwise.
+ * @throws IOException In case of an failure.
+ */
+ public JenkinsServer deleteJob(String jobName, boolean crumbFlag) throws IOException {
client.post("/job/" + EncodingUtils.encode(jobName) + "/doDelete", crumbFlag);
+ return this;
}
- /*
+ /**
* Disable a job from jenkins
- *
- * @throws IOException
+ *
+ * @param jobName The name of the job which should be disabled.
+ * @throws IOException in case of an error.
*/
- public void disableJob(String jobName) throws IOException {
- client.post("/job/" + EncodingUtils.encode(jobName) + "/disable");
+ public JenkinsServer disableJob(String jobName) throws IOException {
+ return disableJob(jobName, false);
}
/**
* Disable a job from Jenkins.
*
- * @param jobName
- * The name of the job to be deleted.
- * @param crumbFlag
- * The crumFlag.
- * @throws IOException
- * In case of an failure.
+ * @param jobName The name of the job to be deleted.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException In case of an failure.
*/
- public void disableJob(String jobName, boolean crumbFlag) throws IOException {
+ public JenkinsServer disableJob(String jobName, boolean crumbFlag) throws IOException {
client.post("/job/" + EncodingUtils.encode(jobName) + "/disable", crumbFlag);
+ return this;
}
- /*
+ /**
* Enable a job from jenkins
- *
- * @throws IOException
+ *
+ * @param jobName name of the job which should be enabled.
+ * @throws IOException In case of an failure.
*/
- public void enableJob(String jobName) throws IOException {
- client.post("/job/" + EncodingUtils.encode(jobName) + "/enable");
+ public JenkinsServer enableJob(String jobName) throws IOException {
+ return enableJob(jobName, false);
}
/**
* Enable a job from Jenkins.
*
- * @param jobName
- * The name of the job to be deleted.
- * @param crumbFlag
- * The crumFlag.
- * @throws IOException
- * In case of an failure.
+ * @param jobName The name of the job to be deleted.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException In case of an failure.
*/
- public void enableJob(String jobName, boolean crumbFlag) throws IOException {
+ public JenkinsServer enableJob(String jobName, boolean crumbFlag) throws IOException {
client.post("/job/" + EncodingUtils.encode(jobName) + "/enable", crumbFlag);
+ return this;
}
/**
@@ -584,15 +785,36 @@ public void enableJob(String jobName, boolean crumbFlag) throws IOException {
* recommended to use heuristics to check your return string for stack
* traces by detecting strings like "groovy.lang.(something)Exception".
*
- * @param script
- * @return results
- * @throws IOException
+ * @param script The script to be executed.
+ * @return results The results of the script.
+ * @throws IOException in case of an error.
*/
public String runScript(String script) throws IOException {
- return client.post_text("/scriptText", "script=" + script, ContentType.APPLICATION_FORM_URLENCODED, false);
+ return runScript(script, false);
+ }
+
+ /**
+ * Runs the provided groovy script on the server and returns the result.
+ *
+ * This is similar to running groovy scripts using the script console.
+ *
+ * In the instance where your script causes an exception, the server still
+ * returns a 200 status, so detecting errors is very challenging. It is
+ * recommended to use heuristics to check your return string for stack
+ * traces by detecting strings like "groovy.lang.(something)Exception".
+ *
+ * @param script The script to run.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @return results The results of the run of the script.
+ * @throws IOException in case of an error.
+ */
+ public String runScript(String script, boolean crumbFlag) throws IOException {
+ return client.post_text("/scriptText", "script=" + script, ContentType.APPLICATION_FORM_URLENCODED, crumbFlag);
}
public Queue getQueue() throws IOException {
+ // TODO: Check if using depth=1 is a good idea?
return client.get("queue/?depth=1", Queue.class);
}
@@ -600,10 +822,10 @@ public QueueItem getQueueItem(QueueReference ref) throws IOException {
try {
String url = ref.getQueueItemUrlPart();
// "/queue/item/" + id
- QueueItem job = client.get(url, QueueItem.class);
- job.setClient(client);
+ QueueItem queueItem = client.get(url, QueueItem.class);
+ queueItem.setClient(client);
- return job;
+ return queueItem;
} catch (HttpResponseException e) {
if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
return null;
@@ -628,16 +850,146 @@ public Build getBuild(QueueItem q) throws IOException {
throw e;
}
}
+
+ /**
+ * Rename a job
+ *
+ * @param oldJobName existing job name.
+ * @param newJobName The new job name.
+ * @throws IOException In case of a failure.
+ */
+ public JenkinsServer renameJob(String oldJobName, String newJobName) throws IOException {
+ return renameJob(null, oldJobName, newJobName, false);
+ }
+
+ /**
+ * Rename a job
+ *
+ * @param oldJobName existing job name.
+ * @param newJobName The new job name.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException In case of a failure.
+ */
+ public JenkinsServer renameJob(String oldJobName, String newJobName, Boolean crumbFlag) throws IOException {
+ renameJob(null, oldJobName, newJobName, crumbFlag);
+ return this;
+ }
+
+ /**
+ * Rename a job
+ *
+ * @param folder {@link FolderJob}
+ * @param oldJobName existing job name.
+ * @param newJobName The new job name.
+ * @throws IOException In case of a failure.
+ */
+ public JenkinsServer renameJob(FolderJob folder, String oldJobName, String newJobName) throws IOException {
+ return renameJob(folder, oldJobName, newJobName, false);
+ }
+
+ /**
+ * Rename a job
+ *
+ * @param folder {@link FolderJob}
+ * @param oldJobName existing job name.
+ * @param newJobName The new job name.
+ * @param crumbFlag true to add crumbIssuer
+ * false otherwise.
+ * @throws IOException In case of a failure.
+ */
+ public JenkinsServer renameJob(FolderJob folder, String oldJobName, String newJobName, Boolean crumbFlag)
+ throws IOException {
+ client.post(UrlUtils.toJobBaseUrl(folder, oldJobName)
+ + "/doRename?newName=" + EncodingUtils.formParameter(newJobName),
+ crumbFlag);
+ return this;
+ }
+
+
/**
- * Rename a job
- *
- * @param jobName Existing Job name
- * @param newJobName New Job Name
- * @throws IOException In case of a failure.
+ * Closes underlying resources.
+ * Closed instances should no longer be used
+ * Closing an already closed instance has no side effects
+ */
+ @Override
+ public void close() {
+ client.close();
+ }
+
+
+ /**
+ * Restart Jenkins without waiting for any existing build to complete
+ *
+ * @param crumbFlag
+ * true to add crumbIssuer false
+ * otherwise.
+ * @throws IOException
+ * in case of an error.
+ */
+ public JenkinsServer restart(Boolean crumbFlag) throws IOException {
+ try {
+ client.post("/restart", crumbFlag);
+ } catch (org.apache.http.client.ClientProtocolException e) {
+ LOGGER.error("restart()", e);
+ }
+ return this;
+ }
+
+ /**
+ * safeRestart: Puts Jenkins into the quiet mode, wait for existing builds
+ * to be completed, and then restart Jenkins
+ *
+ * @param crumbFlag
+ * true to add crumbIssuer false
+ * otherwise.
+ * @throws IOException
+ * in case of an error.
+ */
+ public JenkinsServer safeRestart(Boolean crumbFlag) throws IOException {
+ try {
+ client.post("/safeRestart", crumbFlag);
+ } catch (org.apache.http.client.ClientProtocolException e) {
+ LOGGER.error("safeRestart()", e);
+ }
+ return this;
+ }
+
+ /**
+ * Shutdown Jenkins without waiting for any existing build to complete
+ *
+ * @param crumbFlag
+ * true to add crumbIssuer false
+ * otherwise.
+ * @throws IOException
+ * in case of an error.
+ */
+ public JenkinsServer exit(Boolean crumbFlag) throws IOException {
+ try {
+ client.post("/exit", crumbFlag);
+ } catch (org.apache.http.client.ClientProtocolException e) {
+ LOGGER.error("exit()", e);
+ }
+ return this;
+ }
+
+ /**
+ * safeExit: Puts Jenkins into the quiet mode, wait for existing builds to
+ * be completed, and then shut down Jenkins
+ *
+ * @param crumbFlag
+ * true to add crumbIssuer false
+ * otherwise.
+ * @throws IOException
+ * in case of an error.
*/
- public void renameJob(String jobName, String newJobName) throws IOException {
- client.post(
- "/job/" + EncodingUtils.encode(jobName) + "/doRename?newName=" + EncodingUtils.encodeParam(newJobName));
+ public JenkinsServer safeExit(Boolean crumbFlag) throws IOException {
+ try {
+ client.post("/safeExit", crumbFlag);
+ } catch (org.apache.http.client.ClientProtocolException e) {
+ LOGGER.error("safeExit()", e);
+ }
+ return this;
}
}
diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsTriggerHelper.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsTriggerHelper.java
new file mode 100644
index 00000000..8084eafb
--- /dev/null
+++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsTriggerHelper.java
@@ -0,0 +1,191 @@
+package com.offbytwo.jenkins;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+import com.offbytwo.jenkins.model.Build;
+import com.offbytwo.jenkins.model.BuildResult;
+import com.offbytwo.jenkins.model.BuildWithDetails;
+import com.offbytwo.jenkins.model.JobWithDetails;
+import com.offbytwo.jenkins.model.QueueItem;
+import com.offbytwo.jenkins.model.QueueReference;
+
+/**
+ * collection of convenient methods which use methods from {@link JenkinsServer}
+ * etc.
+ *
+ * @author Karl Heinz Marbaise
+ *
+ */
+public class JenkinsTriggerHelper {
+
+ private final JenkinsServer server;
+ private final Long retryInterval;
+ private static final Long DEFAULT_RETRY_INTERVAL = 200L;
+
+ public JenkinsTriggerHelper(JenkinsServer server) {
+ this.server = server;
+ this.retryInterval = DEFAULT_RETRY_INTERVAL;
+ }
+
+ public JenkinsTriggerHelper(JenkinsServer server, Long retryInterval) {
+ this.server = server;
+ this.retryInterval = retryInterval;
+ }
+
+ /**
+ * This method will trigger a build of the given job and will wait until the
+ * builds is ended or if the build has been cancelled.
+ *
+ * @param jobName The name of the job which should be triggered.
+ * @return In case of an cancelled job you will get
+ * {@link BuildWithDetails#getResult()}
+ * {@link BuildResult#CANCELLED}. So you have to check first if the
+ * build result is {@code CANCELLED}.
+ * @throws IOException in case of errors.
+ * @throws InterruptedException In case of interrupts.
+ */
+ public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName) throws IOException, InterruptedException {
+ return triggerJobAndWaitUntilFinished(jobName, false);
+ }
+
+ /**
+ * This method will trigger a build of the given job and will wait until the
+ * builds is ended or if the build has been cancelled.
+ *
+ * @param jobName The name of the job which should be triggered.
+ * @param params the job parameters
+ * @return In case of an cancelled job you will get
+ * {@link BuildWithDetails#getResult()}
+ * {@link BuildResult#CANCELLED}. So you have to check first if the
+ * build result is {@code CANCELLED}.
+ * @throws IOException in case of errors.
+ * @throws InterruptedException In case of interrupts.
+ */
+ public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName, Maptrue or false.
+ * @return In case of an cancelled job you will get
+ * {@link BuildWithDetails#getResult()}
+ * {@link BuildResult#CANCELLED}. So you have to check first if the
+ * build result is {@code CANCELLED}.
+ * @throws IOException in case of errors.
+ * @throws InterruptedException In case of interrupts.
+ */
+ public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName, Maptrue or false.
+ * @return In case of an cancelled job you will get
+ * {@link BuildWithDetails#getResult()}
+ * {@link BuildResult#CANCELLED}. So you have to check first if the
+ * build result is {@code CANCELLED}.
+ * @throws IOException in case of errors.
+ * @throws InterruptedException In case of interrupts.
+ */
+ public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName, Maptrue or false.
+ * @return In case of an cancelled job you will get
+ * {@link BuildWithDetails#getResult()}
+ * {@link BuildResult#CANCELLED}. So you have to check first if the
+ * build result is {@code CANCELLED}.
+ * @throws IOException in case of errors.
+ * @throws InterruptedException In case of interrupts.
+ */
+ public BuildWithDetails triggerJobAndWaitUntilFinished(String jobName, boolean crumbFlag)
+ throws IOException, InterruptedException {
+ JobWithDetails job = this.server.getJob(jobName);
+ QueueReference queueRef = job.build(crumbFlag);
+
+ return triggerJobAndWaitUntilFinished(jobName, queueRef);
+ }
+
+ /**
+ * @param jobName The name of the job.
+ * @param queueRef {@link QueueReference}
+ * @return In case of an cancelled job you will get
+ * {@link BuildWithDetails#getResult()}
+ * {@link BuildResult#CANCELLED}. So you have to check first if the
+ * build result is {@code CANCELLED}.
+ * @throws IOException in case of errors.
+ * @throws InterruptedException In case of interrupts.
+ */
+ private BuildWithDetails triggerJobAndWaitUntilFinished(String jobName, QueueReference queueRef)
+ throws IOException, InterruptedException {
+ JobWithDetails job = this.server.getJob(jobName);
+ QueueItem queueItem = this.server.getQueueItem(queueRef);
+
+ while (!queueItem.isCancelled() && job.isInQueue()) {
+ Thread.sleep(retryInterval);
+ job = this.server.getJob(jobName);
+ queueItem = this.server.getQueueItem(queueRef);
+ }
+
+ Build build = server.getBuild(queueItem);
+ if (queueItem.isCancelled()) {
+ return build.details();
+ }
+
+ boolean isBuilding = build.details().isBuilding();
+ while (isBuilding) {
+ Thread.sleep(retryInterval);
+ isBuilding = build.details().isBuilding();
+ }
+
+ return build.details();
+ }
+}
diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java
old mode 100644
new mode 100755
index 322ecd0f..4eadc5c9
--- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java
+++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java
@@ -3,62 +3,61 @@
*
* Distributed under the MIT license: http://opensource.org/licenses/MIT
*/
-
package com.offbytwo.jenkins.client;
-import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
-import static org.apache.commons.lang.StringUtils.isNotBlank;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.offbytwo.jenkins.client.util.EncodingUtils;
+import com.offbytwo.jenkins.client.util.RequestReleasingInputStream;
+import com.offbytwo.jenkins.client.validator.HttpResponseValidator;
+import com.offbytwo.jenkins.model.BaseModel;
+import com.offbytwo.jenkins.model.Crumb;
+import com.offbytwo.jenkins.model.ExtractHeader;
+import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.http.Header;
+import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.Lists;
-import com.google.common.io.ByteStreams;
-import com.offbytwo.jenkins.client.util.EncodingUtils;
-import com.offbytwo.jenkins.client.util.RequestReleasingInputStream;
-//import com.offbytwo.jenkins.client.util.HttpResponseContentExtractor;
-import com.offbytwo.jenkins.client.validator.HttpResponseValidator;
-import com.offbytwo.jenkins.model.BaseModel;
-import com.offbytwo.jenkins.model.Crumb;
-import com.offbytwo.jenkins.model.ExtractHeader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
-import net.sf.json.JSONObject;
+import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
+import com.offbytwo.jenkins.client.util.ResponseUtils;
+import com.offbytwo.jenkins.client.util.UrlUtils;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
-public class JenkinsHttpClient {
- private final Logger LOGGER = LoggerFactory.getLogger( getClass() );
-
- private static final int SO_TIMEOUT_IN_MILLISECONDS = 3000;
- private static final int CONNECTION_TIMEOUT_IN_MILLISECONDS = 500;
+public class JenkinsHttpClient implements JenkinsHttpConnection {
+
+ private final Logger LOGGER = LoggerFactory.getLogger(getClass());
private URI uri;
private CloseableHttpClient client;
@@ -68,16 +67,16 @@ public class JenkinsHttpClient {
private ObjectMapper mapper;
private String context;
-
+
private String jenkinsVersion;
+ public final static String EMPTY_VERSION = "UNKNOWN";
+
/**
* Create an unauthenticated Jenkins HTTP client
*
- * @param uri
- * Location of the jenkins server (ex. http://localhost:8080)
- * @param client
- * Configured CloseableHttpClient to be used
+ * @param uri Location of the jenkins server (ex. http://localhost:8080)
+ * @param client Configured CloseableHttpClient to be used
*/
public JenkinsHttpClient(URI uri, CloseableHttpClient client) {
this.context = uri.getPath();
@@ -89,17 +88,15 @@ public JenkinsHttpClient(URI uri, CloseableHttpClient client) {
this.client = client;
this.httpResponseValidator = new HttpResponseValidator();
// this.contentExtractor = new HttpResponseContentExtractor();
- this.jenkinsVersion = null;
+ this.jenkinsVersion = EMPTY_VERSION;
LOGGER.debug("uri={}", uri.toString());
}
/**
* Create an unauthenticated Jenkins HTTP client
*
- * @param uri
- * Location of the jenkins server (ex. http://localhost:8080)
- * @param builder
- * Configured HttpClientBuilder to be used
+ * @param uri Location of the jenkins server (ex. http://localhost:8080)
+ * @param builder Configured HttpClientBuilder to be used
*/
public JenkinsHttpClient(URI uri, HttpClientBuilder builder) {
this(uri, builder.build());
@@ -108,39 +105,33 @@ public JenkinsHttpClient(URI uri, HttpClientBuilder builder) {
/**
* Create an unauthenticated Jenkins HTTP client
*
- * @param uri
- * Location of the jenkins server (ex. http://localhost:8080)
+ * @param uri Location of the jenkins server (ex. http://localhost:8080)
*/
public JenkinsHttpClient(URI uri) {
this(uri, HttpClientBuilder.create());
- this.context = uri.getPath();
-
- if (!context.endsWith("/")) {
- context += "/";
- }
- this.uri = uri;
- this.mapper = getDefaultMapper();
-
- HttpParams httpParams = new BasicHttpParams();
- httpParams.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SO_TIMEOUT_IN_MILLISECONDS);
- httpParams.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIMEOUT_IN_MILLISECONDS);
-
- this.httpResponseValidator = new HttpResponseValidator();
- LOGGER.debug("uri={}", uri.toString());
}
/**
* Create an authenticated Jenkins HTTP client
*
- * @param uri
- * Location of the jenkins server (ex. http://localhost:8080)
- * @param username
- * Username to use when connecting
- * @param password
- * Password or auth token to use when connecting
+ * @param uri Location of the jenkins server (ex. http://localhost:8080)
+ * @param username Username to use when connecting
+ * @param password Password or auth token to use when connecting
*/
public JenkinsHttpClient(URI uri, String username, String password) {
- this(uri, addAuthentication(HttpClientBuilder.create(), uri, username, password));
+ this(uri, HttpClientBuilder.create(), username, password);
+ }
+
+ /**
+ * Create an authenticated Jenkins HTTP client
+ *
+ * @param uri Location of the jenkins server (ex. http://localhost:8080)
+ * @param builder Configured HttpClientBuilder to be used
+ * @param username Username to use when connecting
+ * @param password Password or auth token to use when connecting
+ */
+ public JenkinsHttpClient(URI uri, HttpClientBuilder builder, String username, String password) {
+ this(uri, addAuthentication(builder, uri, username, password));
if (isNotBlank(username)) {
localContext = new BasicHttpContext();
localContext.setAttribute("preemptive-auth", new BasicScheme());
@@ -148,23 +139,14 @@ public JenkinsHttpClient(URI uri, String username, String password) {
}
/**
- * Perform a GET request and parse the response to the given class
- *
- * @param path
- * path to request, can be relative or absolute
- * @param cls
- * class of the response
- * @param -' (hyphen) and '.' (dot) separators,1.0alpha1 => [1, 0, alpha, 1]alpha or abeta or bmilestone or mrc or crsnapshot(the empty string) or ga or finalsp> the
+ * given version.
+ *
+ * @param version The version to compare with.
+ * @return true or false.
+ */
+ public boolean isGreaterThan(String version) {
+ JenkinsVersion create = create(version);
+ return this.cv.compareTo(create.cv) > 0;
+ }
+
+ public boolean isGreaterThan(JenkinsVersion jv) {
+ return this.cv.compareTo(jv.cv) > 0;
+ }
+
+ /**
+ * This will check if the current instance version is >= the
+ * given version.
+ *
+ * @param version The version to compare with.
+ * @return true or false.
+ */
+ public boolean isGreaterOrEqual(String version) {
+ JenkinsVersion create = create(version);
+ return this.cv.compareTo(create.cv) >= 0;
+ }
+
+ public boolean isGreaterOrEqual(JenkinsVersion jv) {
+ return this.cv.compareTo(jv.cv) >= 0;
+ }
+
+ /**
+ * This will check if the current instance version is < the
+ * given version.
+ *
+ * @param version The version to compare with.
+ * @return true or false.
+ */
+ public boolean isLessThan(String version) {
+ JenkinsVersion create = create(version);
+ return this.cv.compareTo(create.cv) < 0;
+ }
+
+ public boolean isLessThan(JenkinsVersion jv) {
+ return this.cv.compareTo(jv.cv) < 0;
+ }
+
+ /**
+ * This will check if the current instance version is <= the
+ * given version.
+ *
+ * @param version The version to compare with.
+ * @return true or false.
+ */
+ public boolean isLessOrEqual(String version) {
+ JenkinsVersion create = create(version);
+ return this.cv.compareTo(create.cv) <= 0;
+ }
+
+ public boolean isLessOrEqual(JenkinsVersion jv) {
+ return this.cv.compareTo(jv.cv) <= 0;
+ }
+
+ /**
+ * This will check if the current instance version is = the
+ * given version.
+ *
+ * @param version The version to compare with.
+ * @return true or false.
+ */
+ public boolean isEqualTo(String version) {
+ JenkinsVersion create = create(version);
+ return this.cv.compareTo(create.cv) == 0;
+ }
+
+ public boolean isEqualTo(JenkinsVersion jv) {
+ return this.cv.compareTo(jv.cv) == 0;
+ }
+
+ @Override
+ public int compareTo(JenkinsVersion o) {
+ return this.compareTo(o);
+ }
+
+ public String getLiteralVersion() {
+ return literalVersion;
+ }
+
+ @Override
+ public String toString() {
+ return literalVersion;
+ }
+}
\ No newline at end of file
diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/helper/Range.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/helper/Range.java
index 642fd8d5..cdbdc60a 100644
--- a/jenkins-client/src/main/java/com/offbytwo/jenkins/helper/Range.java
+++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/helper/Range.java
@@ -16,21 +16,29 @@
* The same as {0,N}.
* * You can use the {@link Range} class like this: - * + * *
* Range fromAndTo = Range.build().from(1).to(5); * Range fromOnly = Range.build().from(3).build(); * Range toOnly = Range.build().to(5).build(); * Range only = Range.build().only(3); *- * - * @author Karl Heinz Marbaise * + * @author Karl Heinz Marbaise */ public final class Range { + /** + * This represents {@code {} (left curly bracket). + */ + public static final String CURLY_BRACKET_OPEN = "%7B"; + /** + * This represents {@code }} (right curly bracket). + */ + public static final String CURLY_BRACKET_CLOSE = "%7D"; + private Integer from; private Integer to; @@ -57,7 +65,7 @@ private Range setTo(int to) { public String getRangeString() { StringBuilder sb = new StringBuilder(); - sb.append("{"); + sb.append(CURLY_BRACKET_OPEN); if (this.from != null) { sb.append(String.format("%d", this.from)); } @@ -68,7 +76,7 @@ public String getRangeString() { sb.append(String.format("%d", this.to)); } - sb.append('}'); + sb.append(CURLY_BRACKET_CLOSE); return sb.toString(); } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/AllMavenBuilds.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/AllMavenBuilds.java new file mode 100644 index 00000000..3503b0f2 --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/AllMavenBuilds.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013 Cosmin Stejerean, Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ + +package com.offbytwo.jenkins.model; + +import java.util.List; + +/** + * This class is only needed to get all builds in + * {@link MavenJobWithDetails#getAllBuilds()}. + * + * @author Karl Heinz Marbaise + * + * NOTE: This class is not part of any public API + */ +class AllMavenBuilds extends BaseModel { + private List
add or edit or delete
+ * @see EditType
*/
- // TODO: Think about it if its possible to use an enum type?
- private String editType; // edit, ?
+ private String editType;
private String file;
+ /**
+ * Return the SCM operation.
+ * @return the SCM operation, add or edit or delete
+ * @see EditType
+ */
public String getEditType() {
return editType;
}
- public void setEditType(String editType) {
+ /**
+ * Sets the SCM operation.
+ * @param editType the SCM operation, add or edit or delete
+ * @see EditType
+ */
+ public BuildChangeSetPath setEditType(String editType) {
this.editType = editType;
+ return this;
}
public String getFile() {
return file;
}
- public void setFile(String file) {
+ public BuildChangeSetPath setFile(String file) {
this.file = file;
+ return this;
}
@Override
diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildResult.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildResult.java
index e4aad42f..64b695c6 100644
--- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildResult.java
+++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildResult.java
@@ -7,5 +7,26 @@
package com.offbytwo.jenkins.model;
public enum BuildResult {
- FAILURE, UNSTABLE, REBUILDING, BUILDING, ABORTED, SUCCESS, UNKNOWN, NOT_BUILT
+ FAILURE, UNSTABLE, REBUILDING, BUILDING,
+ /**
+ * This means a job was already running and has been aborted.
+ */
+ ABORTED,
+ /**
+ *
+ */
+ SUCCESS,
+ /**
+ * ?
+ */
+ UNKNOWN,
+ /**
+ * This is returned if a job has never been built.
+ */
+ NOT_BUILT,
+ /**
+ * This will be the result of a job in cases where it has been cancelled
+ * during the time in the queue.
+ */
+ CANCELLED
}
diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java
index f9ec3c25..d3ce5842 100644
--- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java
+++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java
@@ -6,33 +6,151 @@
package com.offbytwo.jenkins.model;
-import com.google.common.base.Predicate;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.offbytwo.jenkins.helper.BuildConsoleStreamListener;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toMap;
+
+/**
+ * This class represents build information with details about what has been done
+ * like duration start and of course the build result.
+ *
+ */
+public class BuildWithDetails extends Build {
-import static com.google.common.collect.Collections2.filter;
+ private final Logger LOGGER = LoggerFactory.getLogger(getClass());
-public class BuildWithDetails extends Build {
+ public final static String TEXT_SIZE_HEADER = "x-text-size";
+ public final static String MORE_DATA_HEADER = "x-more-data";
+
+ /**
+ * This will be returned by the API in cases where the build has never run.
+ * For example {@link Build#BUILD_HAS_NEVER_RUN}
+ */
+ public static final BuildWithDetails BUILD_HAS_NEVER_RUN = new BuildWithDetails() {
+
+ @Override
+ public List getActions() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List