From 42a15c9e35ec8c8af61bf3039f76f90396a59d60 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sun, 6 Aug 2017 16:49:42 +0200 Subject: [PATCH 01/68] Fixed link. --- ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 66711150..2c43e996 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -11,7 +11,7 @@ Splitting fix made for jacoco reports from Jenkins #98. Thanks to Shah, Prince. - * [Fixed Issue 217][issue- 217] + * [Fixed Issue 217][issue-217] Added new api for streaming build logs From 2f9c8b407aa63ea69bb5ee4c74c0e8ec128d671c Mon Sep 17 00:00:00 2001 From: Jesper Terkelsen Date: Fri, 25 Aug 2017 09:08:21 +0200 Subject: [PATCH 02/68] JENKINS-46445 Add support for both client TLS and basic authentication. In some setups both client certificate TLS authentication and username password authentication is needed. Here is how you would set it up: - Create a sslContext - add it along with credentials to the new constructor HttpClientBuilder builder = HttpClientBuilder.create(); builder.setSslcontext(sslContext); JenkinsHttpClient client = new JenkinsHttpClient(uri, builder, username, password); JenkinsServer jenkins = new JenkinsServer(client); --- ReleaseNotes.md | 11 +++++++++++ .../offbytwo/jenkins/client/JenkinsHttpClient.java | 14 +++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 2c43e996..0fee6d50 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,17 @@ ## Release 0.3.8 (NOT RELEASED YET) + * [JENKINS-46445](https://issues.jenkins-ci.org/browse/JENKINS-46445) + + Add support for both client TLS and basic authentication. + + ```java + HttpClientBuilder builder = HttpClientBuilder.create(); + builder.setSslcontext(sslContext); + JenkinsHttpClient client = new JenkinsHttpClient(uri, builder, username, password); + JenkinsServer jenkins = new JenkinsServer(client); + ``` + * [Fixed Issue 268][issue-268] NullPointerException is thrown unless isRunning() is called first. 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 index 8c5c467a..33f4b167 100755 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java @@ -115,7 +115,19 @@ public JenkinsHttpClient(URI uri) { * @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()); From 973958ebc33090b0e33dccc8c87b4bbc760646bd Mon Sep 17 00:00:00 2001 From: Jesper Terkelsen Date: Fri, 25 Aug 2017 23:56:13 +0200 Subject: [PATCH 03/68] JENKINS-46472 Ability to modify offline cause for offline computers. Added ability to modify offline cause for offline computers. ComputerWithDetails computer = ... if (!computer.getOffline()){ computer.toggleOffline(); computer.changeOfflineCause("Scheduled for termination"); } --- ReleaseNotes.md | 12 ++++++++++++ .../jenkins/model/ComputerWithDetails.java | 17 +++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 2c43e996..d73d6f40 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,18 @@ ## Release 0.3.8 (NOT RELEASED YET) + * [JENKINS-46472](https://issues.jenkins-ci.org/browse/JENKINS-46472) + + Added ability to modify offline cause for offline computers. + + ```java + ComputerWithDetails computer = ... + if (!computer.getOffline()){ + computer.toggleOffline(); + computer.changeOfflineCause("Scheduled for termination"); + } + ``` + * [Fixed Issue 268][issue-268] NullPointerException is thrown unless isRunning() is called first. diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java index b1df2eef..c565f8a2 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java @@ -97,6 +97,23 @@ public void toggleOffline() throws IOException { toggleOffline( false ); } + public void changeOfflineCause(String cause, boolean crumbFlag) throws IOException { + String name; + if ("master".equals(displayName)) { + name = "(master)"; + } else { + name = UrlEscapers.urlPathSegmentEscaper().escape(displayName); + } + + Map data = new HashMap(); + data.put( "offlineMessage", cause ); + client.post_form("/computer/" + name + "/changeOfflineCause?", data, crumbFlag); + } + + public void changeOfflineCause(String cause) throws IOException { + changeOfflineCause(cause, false); + } + public Boolean getManualLaunchAllowed() { return manualLaunchAllowed; } From 4e317ed7cd34dbc01169d7b808b06748e33d26db Mon Sep 17 00:00:00 2001 From: Liren Tu Date: Fri, 8 Sep 2017 20:08:50 -0700 Subject: [PATCH 04/68] Fixed #282 o Check the correct parameter when converting cause to a BuildCause object. --- ReleaseNotes.md | 5 +++++ .../java/com/offbytwo/jenkins/model/BuildWithDetails.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 2c43e996..f0f7142b 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,11 @@ ## Release 0.3.8 (NOT RELEASED YET) + * [Fixed Issue 282][issue-282] + + `NullPointerException` may be thrown if `upstreamUrl` is `null` when + converting cause to `BuildCause` object. + * [Fixed Issue 268][issue-268] NullPointerException is thrown unless isRunning() is called first. 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 9812a00d..2feea4f9 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 @@ -290,7 +290,7 @@ private BuildCause convertToBuildCause(Map cause) { } String upstreamUrl = (String) cause.get("upstreamUrl"); - if (!Strings.isNullOrEmpty(upstreamProject)) { + if (!Strings.isNullOrEmpty(upstreamUrl)) { cause_object.setUpstreamUrl(upstreamUrl); } From 610ded57bf9d359b0e979d4c875f67dc6b8f54ef Mon Sep 17 00:00:00 2001 From: Dell Green Date: Thu, 5 Oct 2017 20:15:38 +0100 Subject: [PATCH 05/68] Refactor: #291, useful utility methods refactored into utility classes --- ReleaseNotes.md | 4 + .../com/offbytwo/jenkins/JenkinsServer.java | 108 +----- .../jenkins/client/JenkinsHttpClient.java | 90 ++--- .../jenkins/client/util/ResponseUtils.java | 38 ++ .../jenkins/client/util/UrlUtils.java | 156 +++++++++ .../jenkins/client/JenkinsHttpClientTest.java | 56 +++ .../client/util/ResponseUtilsTest.java | 49 +++ .../jenkins/client/util/UrlUtilsTest.java | 324 ++++++++++++++++++ 8 files changed, 677 insertions(+), 148 deletions(-) create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/ResponseUtils.java create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/UrlUtils.java create mode 100644 jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java create mode 100644 jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/ResponseUtilsTest.java create mode 100644 jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/UrlUtilsTest.java diff --git a/ReleaseNotes.md b/ReleaseNotes.md index f0f7142b..c4a6f533 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,10 @@ ## Release 0.3.8 (NOT RELEASED YET) + * [Refactor Issue 291][issue-291] + + Useful utility methods refactored into utility classes. + * [Fixed Issue 282][issue-282] `NullPointerException` may be thrown if `upstreamUrl` is `null` when diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java index 7b8f77a8..0a6f79a4 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.net.URI; -import java.util.Arrays; import java.util.List; import java.util.Map; @@ -27,6 +26,7 @@ import com.google.common.collect.Maps; import com.offbytwo.jenkins.client.JenkinsHttpClient; import com.offbytwo.jenkins.client.util.EncodingUtils; +import com.offbytwo.jenkins.client.util.UrlUtils; import com.offbytwo.jenkins.helper.JenkinsVersion; import com.offbytwo.jenkins.model.Build; import com.offbytwo.jenkins.model.Computer; @@ -155,7 +155,7 @@ public Map getJobs(String view) throws IOException { * @throws IOException in case of an error. */ public Map getJobs(FolderJob folder, String view) throws IOException { - String path = toBaseUrl(folder); + String path = UrlUtils.toBaseUrl(folder); Class viewClass = MainView.class; if (view != null) { path = path + "view/" + EncodingUtils.encode(view) + "/"; @@ -192,7 +192,7 @@ public Map getViews() throws IOException { public Map getViews(FolderJob folder) throws IOException { // This is much better than using &depth=2 // http://localhost:8080/api/json?pretty&tree=views[name,url,jobs[name,url]] - List views = client.get(toBaseUrl(folder) + "?tree=views[name,url,jobs[name,url]]", MainView.class).getViews(); + List views = client.get(UrlUtils.toBaseUrl(folder) + "?tree=views[name,url,jobs[name,url]]", MainView.class).getViews(); return Maps.uniqueIndex(views, new Function() { @Override public String apply(View view) { @@ -232,7 +232,7 @@ public View getView(String name) throws IOException { */ public View getView(FolderJob folder, String name) throws IOException { try { - View resultView = client.get(toViewBaseUrl(folder, name) + "/", View.class); + View resultView = client.get(UrlUtils.toViewBaseUrl(folder, name) + "/", View.class); resultView.setClient(client); // TODO: Think about the following? Does there exists a simpler/more @@ -262,7 +262,7 @@ public View getView(FolderJob folder, String name) throws IOException { * @throws IOException in case of an error. */ public JobWithDetails getJob(String jobName) throws IOException { - return getJob(null, parseFullName(jobName)); + return getJob(null, UrlUtils.toFullJobPath(jobName)); } /** @@ -275,7 +275,7 @@ public JobWithDetails getJob(String jobName) throws IOException { */ public JobWithDetails getJob(FolderJob folder, String jobName) throws IOException { try { - JobWithDetails job = client.get(toJobBaseUrl(folder, jobName), JobWithDetails.class); + JobWithDetails job = client.get(UrlUtils.toJobBaseUrl(folder, jobName), JobWithDetails.class); job.setClient(client); return job; @@ -290,12 +290,12 @@ public JobWithDetails getJob(FolderJob folder, String jobName) throws IOExceptio } public MavenJobWithDetails getMavenJob(String jobName) throws IOException { - return getMavenJob(null, parseFullName(jobName)); + return getMavenJob(null, UrlUtils.toFullJobPath(jobName)); } public MavenJobWithDetails getMavenJob(FolderJob folder, String jobName) throws IOException { try { - MavenJobWithDetails job = client.get(toJobBaseUrl(folder, jobName), MavenJobWithDetails.class); + MavenJobWithDetails job = client.get(UrlUtils.toJobBaseUrl(folder, jobName), MavenJobWithDetails.class); job.setClient(client); return job; @@ -381,7 +381,7 @@ public void createJob(FolderJob folder, String jobName, String jobXml) throws IO * @throws IOException in case of an error. */ public void createJob(FolderJob folder, String jobName, String jobXml, Boolean crumbFlag) throws IOException { - client.post_xml(toBaseUrl(folder) + "createItem?name=" + EncodingUtils.encodeParam(jobName), jobXml, crumbFlag); + client.post_xml(UrlUtils.toBaseUrl(folder) + "createItem?name=" + EncodingUtils.encodeParam(jobName), jobXml, crumbFlag); } /** @@ -433,7 +433,7 @@ public void createView(FolderJob folder, String viewName, String viewXml) throws * @throws IOException in case of an error. */ public void createView(FolderJob folder, String viewName, String viewXml, Boolean crumbFlag) throws IOException { - client.post_xml(toBaseUrl(folder) + "createView?name=" + EncodingUtils.encodeParam(viewName), viewXml, + client.post_xml(UrlUtils.toBaseUrl(folder) + "createView?name=" + EncodingUtils.encodeParam(viewName), viewXml, crumbFlag); } @@ -484,7 +484,7 @@ public void createFolder(FolderJob folder, String jobName, Boolean crumbFlag) th // here ImmutableMap params = ImmutableMap.of("mode", "com.cloudbees.hudson.plugins.folder.Folder", "name", EncodingUtils.encodeParam(jobName), "from", "", "Submit", "OK"); - client.post_form(toBaseUrl(folder) + "createItem?", params, crumbFlag); + client.post_form(UrlUtils.toBaseUrl(folder) + "createItem?", params, crumbFlag); } /** @@ -507,7 +507,7 @@ public String getJobXml(String jobName) throws IOException { * @throws IOException in case of an error. */ public String getJobXml(FolderJob folder, String jobName) throws IOException { - return client.get(toJobBaseUrl(folder, jobName) + "/config.xml"); + return client.get(UrlUtils.toJobBaseUrl(folder, jobName) + "/config.xml"); } /** @@ -577,11 +577,11 @@ public void updateView(String viewName, String viewXml, boolean crumbFlag) throw } public void updateView(FolderJob folder, String viewName, String viewXml) throws IOException { - client.post_xml(toBaseUrl(folder) + "view/" + EncodingUtils.encode(viewName) + "/config.xml", viewXml, true); + client.post_xml(UrlUtils.toBaseUrl(folder) + "view/" + EncodingUtils.encode(viewName) + "/config.xml", viewXml, true); } public void updateView(FolderJob folder, String viewName, String viewXml, boolean crumbFlag) throws IOException { - client.post_xml(toBaseUrl(folder) + "view/" + EncodingUtils.encode(viewName) + "/config.xml", viewXml, crumbFlag); + client.post_xml(UrlUtils.toBaseUrl(folder) + "view/" + EncodingUtils.encode(viewName) + "/config.xml", viewXml, crumbFlag); } /** @@ -617,7 +617,7 @@ public void updateJob(String jobName, String jobXml, boolean crumbFlag) throws I * @throws IOException in case of an error. */ public void updateJob(FolderJob folder, String jobName, String jobXml, boolean crumbFlag) throws IOException { - client.post_xml(toJobBaseUrl(folder, jobName) + "/config.xml", jobXml, crumbFlag); + client.post_xml(UrlUtils.toJobBaseUrl(folder, jobName) + "/config.xml", jobXml, crumbFlag); } /** @@ -685,7 +685,7 @@ public void deleteJob(FolderJob folder, String jobName) throws IOException { * @throws IOException in case of problems. */ public void deleteJob(FolderJob folder, String jobName, boolean crumbFlag) throws IOException { - client.post(toJobBaseUrl(folder, jobName) + "/doDelete", crumbFlag); + client.post(UrlUtils.toJobBaseUrl(folder, jobName) + "/doDelete", crumbFlag); } /** @@ -878,80 +878,10 @@ public void renameJob(FolderJob folder, String oldJobName, String newJobName) th */ public void renameJob(FolderJob folder, String oldJobName, String newJobName, Boolean crumbFlag) throws IOException { - client.post(toJobBaseUrl(folder, oldJobName) + "/doRename?newName=" + EncodingUtils.encodeParam(newJobName), - crumbFlag); - } - - /** - * Helper to create a base url in case a folder is given - * - * @param folder the folder or {@code null} - * @return The created base url. - */ - private String toBaseUrl(FolderJob folder) { - String path = "/"; - if (folder != null) { - path = folder.getUrl(); - } - return path; - } - - /** - * Helper to create the base url for a job, with or without a given folder - * - * @param folder the folder or {@code null} - * @param jobName the name of the job. - * @return converted base url. - */ - private String toJobBaseUrl(FolderJob folder, String jobName) { - String jobBaseUrl = toBaseUrl(folder) + "job/"; - - String[] jobNameParts = jobName.split("/"); - for (int i = 0; i < jobNameParts.length; i++) { - jobBaseUrl += EncodingUtils.encode(jobNameParts[i]); - - if (i != jobNameParts.length - 1) { - jobBaseUrl += "/"; - } - } - - return jobBaseUrl; + client.post(UrlUtils.toJobBaseUrl(folder, oldJobName) + + "/doRename?newName=" + EncodingUtils.encodeParam(newJobName), + crumbFlag); } - /** - * Helper to create the base url for a view, with or without a given folder - * - * @param folder the folder or {@code null} - * @param name the of the view. - * @return converted view url. - */ - private String toViewBaseUrl(FolderJob folder, String name) { - return toBaseUrl(folder) + "view/" + EncodingUtils.encode(name); - } - /** - * Parses the provided job name for folders to get the full path for the job. - * @param jobName the fullName of the job. - * @return the path of the job including folders if present. - */ - private String parseFullName(String jobName) - { - if (!jobName.contains("/")) { - return jobName; - } - - List foldersAndJob = Arrays.asList(jobName.split("/")); - - String foldersAndJobName = ""; - - for (int i = 0; i < foldersAndJob.size(); i++) { - foldersAndJobName += foldersAndJob.get(i); - - if (i != foldersAndJob.size() -1) { - foldersAndJobName += "/job/"; - } - } - - return foldersAndJobName; - } } 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 index 8c5c467a..e527e0b2 100755 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java @@ -18,7 +18,6 @@ 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.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.auth.AuthScope; @@ -48,6 +47,8 @@ import java.util.Map; 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; //import com.offbytwo.jenkins.client.util.HttpResponseContentExtractor; @@ -132,10 +133,10 @@ public JenkinsHttpClient(URI uri, String username, String password) { * @throws IOException in case of an error. */ public T get(String path, Class cls) throws IOException { - HttpGet getMethod = new HttpGet(api(path)); + HttpGet getMethod = new HttpGet(UrlUtils.toJsonApiUri(uri, context, path)); HttpResponse response = client.execute(getMethod, localContext); - getJenkinsVersionFromHeader(response); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); try { httpResponseValidator.validateResponse(response); return objectFromResponse(cls, response); @@ -154,9 +155,9 @@ public T get(String path, Class cls) throws IOException * @throws IOException in case of an error. */ public String get(String path) throws IOException { - HttpGet getMethod = new HttpGet(api(path)); + HttpGet getMethod = new HttpGet(UrlUtils.toJsonApiUri(uri, context, path)); HttpResponse response = client.execute(getMethod, localContext); - getJenkinsVersionFromHeader(response); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); LOGGER.debug("get({}), version={}, responseCode={}", path, this.jenkinsVersion, response.getStatusLine().getStatusCode()); try { @@ -200,7 +201,7 @@ public T getQuietly(String path, Class cls) { public InputStream getFile(URI path) throws IOException { HttpGet getMethod = new HttpGet(path); HttpResponse response = client.execute(getMethod, localContext); - getJenkinsVersionFromHeader(response); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); httpResponseValidator.validateResponse(response); return new RequestReleasingInputStream(response.getEntity().getContent(), getMethod); } @@ -222,7 +223,7 @@ public R post(String path, D data, Class cls) throws * @throws IOException in case of an error. */ public R post(String path, D data, Class cls, boolean crumbFlag) throws IOException { - HttpPost request = new HttpPost(api(path)); + HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(uri, context, path)); if (crumbFlag == true) { Crumb crumb = getQuietly("/crumbIssuer", Crumb.class); if (crumb != null) { @@ -236,7 +237,7 @@ public R post(String path, D data, Class cls, boolea request.setEntity(stringEntity); } HttpResponse response = client.execute(request, localContext); - getJenkinsVersionFromHeader(response); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); try { httpResponseValidator.validateResponse(response); @@ -264,14 +265,14 @@ public R post(String path, D data, Class cls, boolea * Perform a POST request using form url encoding. * * This method was added for the purposes of creating folders, but may be - * useful for other API calls as well. - * - * Unlike post and post_xml, the path is *not* modified by adding - * "/api/json". Additionally, the params in data are provided as both - * request parameters including a json parameter, *and* in the - * JSON-formatted StringEntity, because this is what the folder creation - * call required. It is unclear if any other jenkins APIs operate in this - * fashion. + useful for other API calls as well. + + Unlike post and post_xml, the path is *not* modified by adding + "/toJsonApiUri/json". Additionally, the params in data are provided as both + request parameters including a json parameter, *and* in the + JSON-formatted StringEntity, because this is what the folder creation + call required. It is unclear if any other jenkins APIs operate in this + fashion. * * @param path path to request, can be relative or absolute * @param data data to post @@ -291,10 +292,10 @@ public void post_form(String path, Map data, boolean crumbFlag) queryParams.add("json=" + EncodingUtils.encodeParam(JSONObject.fromObject(data).toString())); String value = mapper.writeValueAsString(data); StringEntity stringEntity = new StringEntity(value, ContentType.APPLICATION_FORM_URLENCODED); - request = new HttpPost(noapi(path) + StringUtils.join(queryParams, "&")); + request = new HttpPost(UrlUtils.toNoApiUri(uri, context, path) + StringUtils.join(queryParams, "&")); request.setEntity(stringEntity); } else { - request = new HttpPost(noapi(path)); + request = new HttpPost(UrlUtils.toNoApiUri(uri, context, path)); } if (crumbFlag == true) { @@ -305,7 +306,7 @@ public void post_form(String path, Map data, boolean crumbFlag) } HttpResponse response = client.execute(request, localContext); - getJenkinsVersionFromHeader(response); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); try { httpResponseValidator.validateResponse(response); @@ -331,10 +332,10 @@ public HttpResponse post_form_with_result(String path, List data, HttpPost request; if (data != null) { UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(data); - request = new HttpPost(noapi(path)); + request = new HttpPost(UrlUtils.toNoApiUri(uri, context, path)); request.setEntity(urlEncodedFormEntity); } else { - request = new HttpPost(noapi(path)); + request = new HttpPost(UrlUtils.toNoApiUri(uri, context, path)); } if (crumbFlag == true) { @@ -344,7 +345,7 @@ public HttpResponse post_form_with_result(String path, List data, } } HttpResponse response = client.execute(request, localContext); - getJenkinsVersionFromHeader(response); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); return response; } @@ -362,7 +363,7 @@ public String post_xml(String path, String xml_data) throws IOException { } public String post_xml(String path, String xml_data, boolean crumbFlag) throws IOException { - HttpPost request = new HttpPost(api(path)); + HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(uri, context, path)); if (crumbFlag == true) { Crumb crumb = getQuietly("/crumbIssuer", Crumb.class); if (crumb != null) { @@ -374,7 +375,7 @@ public String post_xml(String path, String xml_data, boolean crumbFlag) throws I request.setEntity(new StringEntity(xml_data, ContentType.create("text/xml", "utf-8"))); } HttpResponse response = client.execute(request, localContext); - getJenkinsVersionFromHeader(response); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); try { httpResponseValidator.validateResponse(response); return IOUtils.toString(response.getEntity().getContent()); @@ -409,7 +410,7 @@ public String post_text(String path, String textData, boolean crumbFlag) throws */ public String post_text(String path, String textData, ContentType contentType, boolean crumbFlag) throws IOException { - HttpPost request = new HttpPost(api(path)); + HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(uri, context, path)); if (crumbFlag == true) { Crumb crumb = get("/crumbIssuer", Crumb.class); if (crumb != null) { @@ -421,7 +422,7 @@ public String post_text(String path, String textData, ContentType contentType, b request.setEntity(new StringEntity(textData, contentType)); } HttpResponse response = client.execute(request, localContext); - getJenkinsVersionFromHeader(response); + jenkinsVersion = ResponseUtils.getJenkinsVersion(response); try { httpResponseValidator.validateResponse(response); return IOUtils.toString(response.getEntity().getContent()); @@ -445,35 +446,11 @@ public void post(String path, boolean crumbFlag) throws IOException { post(path, null, null, crumbFlag); } - private String urlJoin(String path1, String path2) { - if (!path1.endsWith("/")) { - path1 += "/"; - } - if (path2.startsWith("/")) { - path2 = path2.substring(1); - } - return path1 + path2; - } + - private URI api(String path) { - if (!path.toLowerCase().matches("https?://.*")) { - path = urlJoin(this.context, path); - } - if (!path.contains("?")) { - path = urlJoin(path, "api/json"); - } else { - String[] components = path.split("\\?", 2); - path = urlJoin(components[0], "api/json") + "?" + components[1]; - } - return uri.resolve("/").resolve(path.replace(" ", "%20")); - } + - private URI noapi(String path) { - if (!path.toLowerCase().matches("https?://.*")) { - path = urlJoin(this.context, path); - } - return uri.resolve("/").resolve(path); - } + private T objectFromResponse(Class cls, HttpResponse response) throws IOException { InputStream content = response.getEntity().getContent(); @@ -508,12 +485,7 @@ public String getJenkinsVersion() { public boolean isJenkinsVersionSet() { return !EMPTY_VERSION.equals( this.jenkinsVersion ); } - private void getJenkinsVersionFromHeader(HttpResponse response) { - Header[] headers = response.getHeaders("X-Jenkins"); - if (headers.length == 1) { - this.jenkinsVersion = headers[0].getValue(); - } - } + private void releaseConnection(HttpRequestBase httpRequestBase) { httpRequestBase.releaseConnection(); diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/ResponseUtils.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/ResponseUtils.java new file mode 100644 index 00000000..572ff4b6 --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/ResponseUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 Cosmin Stejerean, Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ +package com.offbytwo.jenkins.client.util; + +import org.apache.http.Header; +import org.apache.http.HttpResponse; + +/** + * + * @author Dell Green + */ +public final class ResponseUtils { + + /** + * Utility Class. + */ + private ResponseUtils() { + //do nothing + } + + + + + /** + * Get Jenkins version from supplied response if any. + * @param response the response + * @return the version or empty string + */ + public static String getJenkinsVersion(final HttpResponse response) { + final Header[] hdrs = response.getHeaders("X-Jenkins"); + return hdrs.length == 0 ? "" : hdrs[0].getValue(); + } + + +} diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/UrlUtils.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/UrlUtils.java new file mode 100644 index 00000000..6f8b17d9 --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/UrlUtils.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2013 Cosmin Stejerean, Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ + +package com.offbytwo.jenkins.client.util; + +import com.offbytwo.jenkins.model.FolderJob; +import java.net.URI; + +/** + * Utility class for manipulating API paths. + * @author Dell Green + */ +public final class UrlUtils { + + /** + * The default size to use for string buffers. + */ + private static final int DEFAULT_BUFFER_SIZE = 64; + + /** + * Utility Class. + */ + private UrlUtils() { + //do nothing + } + + + + /** + * Helper to create a base url in case a folder is given + * @param folder the folder or {@code null} + * @return The created base url. + */ + public static String toBaseUrl(final FolderJob folder) { + return folder == null ? "/" : folder.getUrl(); + } + + + + /** + * Helper to create the base url for a job, with or without a given folder + * @param folder the folder or {@code null} + * @param jobName the name of the job. + * @return converted base url. + */ + public static String toJobBaseUrl(final FolderJob folder, final String jobName) { + final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); + sb.append(UrlUtils.toBaseUrl(folder)); + if (sb.charAt(sb.length() - 1) != '/') sb.append('/'); + sb.append("job/"); + final String[] jobNameParts = jobName.split("/"); + + for (int i = 0; i < jobNameParts.length; i++) { + sb.append(EncodingUtils.encode(jobNameParts[i])); + if (i != jobNameParts.length - 1) sb.append('/'); + } + return sb.toString(); + } + + + /** + * Helper to create the base url for a view, with or without a given folder + * @param folder the folder or {@code null} + * @param name the of the view. + * @return converted view url. + */ + public static String toViewBaseUrl(final FolderJob folder, final String name) { + final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); + final String base = UrlUtils.toBaseUrl(folder); + sb.append(base); + if (!base.endsWith("/")) sb.append('/'); + sb.append("view/") + .append(EncodingUtils.encode(name)); + return sb.toString(); + } + + + /** + * Parses the provided job name for folders to get the full path for the job. + * @param jobName the fullName of the job. + * @return the path of the job including folders if present. + */ + public static String toFullJobPath(final String jobName) { + final String[] parts = jobName.split("/"); + if (parts.length == 1) return parts[0]; + final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); + + for (int i = 0; i < parts.length; i++) { + sb.append(parts[i]); + if (i != parts.length -1) sb.append("/job/"); + } + return sb.toString(); + } + + + + /** + * Join two paths together taking into account leading/trailing slashes. + * @param path1 the first path + * @param path2 the second path + * @return the joins path + */ + public static String join(final String path1, final String path2) { + if (path1.isEmpty() && path2.isEmpty()) return ""; + if (path1.isEmpty() && !path2.isEmpty()) return path2; + if (path2.isEmpty() && !path1.isEmpty()) return path1; + final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); + sb.append(path1); + if (sb.charAt(sb.length() - 1) == '/') sb.setLength(sb.length() - 1); + if (path2.charAt(0) != '/') sb.append('/'); + sb.append(path2); + return sb.toString(); + } + + + + /** + * Create a JSON URI from the supplied parameters. + * @param uri the server URI + * @param context the server context if any + * @param path the specific API path + * @return new full URI instance + */ + public static URI toJsonApiUri(final URI uri, final String context, final String path) { + String p = path; + if (!p.matches("(?i)https?://.*")) p = join(context, p); + + if (!p.contains("?")) { + p = join(p, "api/json"); + } else { + final String[] components = p.split("\\?", 2); + p = join(components[0], "api/json") + "?" + components[1]; + } + return uri.resolve("/").resolve(p.replace(" ", "%20")); + } + + + + /** + * Create a URI from the supplied parameters. + * @param uri the server URI + * @param context the server context if any + * @param path the specific API path + * @return new full URI instance + */ + public static URI toNoApiUri(final URI uri, final String context, final String path) { + final String p = path.matches("(?i)https?://.*") ? path : join(context, path); + return uri.resolve("/").resolve(p); + } + + + +} diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java new file mode 100644 index 00000000..a55e0560 --- /dev/null +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013 Cosmin Stejerean, Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ +package com.offbytwo.jenkins.client; + +import java.io.ByteArrayInputStream; +import java.net.URI; +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.protocol.HttpContext; +import static org.junit.Assert.assertEquals; +import org.junit.Test; +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; + + + +/** + * + * @author Dell Green + */ +public class JenkinsHttpClientTest { + private static final String URI = "http://localhost/jenkins"; + + + + @Test + public void testGet_String() throws Exception { + final CloseableHttpClient client = mock(CloseableHttpClient.class); + final CloseableHttpResponse response = mock(CloseableHttpResponse.class); + final Header versionHeader = mock(Header.class); + final StatusLine statusLine = mock(StatusLine.class); + final HttpEntity entity = mock(HttpEntity.class); + given(client.execute(any(HttpUriRequest.class), any(HttpContext.class))).willReturn(response); + given(response.getHeaders(anyString())).willReturn(new Header[]{versionHeader}); + given(response.getStatusLine()).willReturn(statusLine); + given(versionHeader.getValue()).willReturn("1.234"); + given(statusLine.getStatusCode()).willReturn(HttpStatus.SC_OK); + given(response.getEntity()).willReturn(entity); + given(entity.getContent()).willReturn(new ByteArrayInputStream("someJson".getBytes())); + final JenkinsHttpClient jclient = new JenkinsHttpClient(new URI(URI), client); + final String s = jclient.get("job/someJob"); + assertEquals("someJson", s); + } + + +} \ No newline at end of file diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/ResponseUtilsTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/ResponseUtilsTest.java new file mode 100644 index 00000000..57e001ea --- /dev/null +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/ResponseUtilsTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Cosmin Stejerean, Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ +package com.offbytwo.jenkins.client.util; + +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import static org.junit.Assert.assertEquals; +import org.junit.Test; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + + + +/** + * + * @author Dell Green + */ +public class ResponseUtilsTest { + + + + @Test + public void testGetJenkinsVersion() { + final Header header = mock(Header.class); + final HttpResponse response = mock(HttpResponse.class); + given(response.getHeaders("X-Jenkins")).willReturn(new Header[]{header}); + given(header.getValue()).willReturn("1.234"); + assertEquals("1.234", ResponseUtils.getJenkinsVersion(response)); + } + + + @Test + public void testGetJenkinsVersion_NoHeader() { + final HttpResponse response = mock(HttpResponse.class); + given(response.getHeaders("X-Jenkins")).willReturn(new Header[0]); + assertEquals("", ResponseUtils.getJenkinsVersion(response)); + } + + + @Test(expected = NullPointerException.class) + public void testGetJenkinsVersion_NullResponse() { + ResponseUtils.getJenkinsVersion(null); + } + + +} \ No newline at end of file diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/UrlUtilsTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/UrlUtilsTest.java new file mode 100644 index 00000000..780600ba --- /dev/null +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/UrlUtilsTest.java @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2013 Cosmin Stejerean, Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ +package com.offbytwo.jenkins.client.util; + +import com.offbytwo.jenkins.model.FolderJob; +import java.net.URI; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import org.junit.Test; + + + +/** + * + * @author Dell Green + */ +public class UrlUtilsTest { + + + + @Test + public void testToBaseUrl_NullFolderJob() { + assertEquals("/", UrlUtils.toBaseUrl(null)); + } + + @Test + public void testToBaseUrl_DefaultFolderJob() { + assertNull("/", UrlUtils.toBaseUrl(new FolderJob())); + } + + + @Test + public void testToBaseUrl() { + final String fpath = "http://localhost/jobs/someFolder/"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + assertEquals(fpath, UrlUtils.toBaseUrl(folderJob)); + } + + + @Test + public void testToJobBaseUrl() { + final String fpath = "http://localhost/jobs/someFolder/"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + final String expected = "http://localhost/jobs/someFolder/job/someJob"; + assertEquals(expected, UrlUtils.toJobBaseUrl(folderJob, "someJob")); + } + + @Test + public void testToJobBaseUrl_NoTrailingFolderSlash() { + final String fpath = "http://localhost/jobs/someFolder"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + final String expected = "http://localhost/jobs/someFolder/job/someJob"; + assertEquals(expected, UrlUtils.toJobBaseUrl(folderJob, "someJob")); + } + + + @Test + public void testToJobBaseUrl_NullFolderJob() { + assertEquals("/job/someJob", UrlUtils.toJobBaseUrl(null, "someJob")); + } + + + @Test + public void testToJobBaseUrl_EmptyJobName() { + final String fpath = "http://localhost/jobs/someFolder"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + final String expected = "http://localhost/jobs/someFolder/job/"; + assertEquals(expected, UrlUtils.toJobBaseUrl(folderJob, "")); + } + + @Test(expected = NullPointerException.class) + public void testToJobBaseUrl_NullJobName() { + final String fpath = "http://localhost/jobs/someFolder"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + UrlUtils.toJobBaseUrl(folderJob, null); + } + + + @Test + public void testToViewBaseUrl() { + final String fpath = "http://localhost/jobs/someFolder/"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + final String expected = "http://localhost/jobs/someFolder/view/someView"; + assertEquals(expected, UrlUtils.toViewBaseUrl(folderJob, "someView")); + } + + @Test + public void testToViewBaseUrl_NoTrailingFolderSlash() { + final String fpath = "http://localhost/jobs/someFolder"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + final String expected = "http://localhost/jobs/someFolder/view/someView"; + assertEquals(expected, UrlUtils.toViewBaseUrl(folderJob, "someView")); + } + + + @Test + public void testToViewBaseUrl_NullFolderJob() { + assertEquals("/view/someView", UrlUtils.toViewBaseUrl(null, "someView")); + } + + + @Test + public void testToViewBaseUrl_EmptyViewName() { + final String fpath = "http://localhost/jobs/someFolder"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + final String expected = "http://localhost/jobs/someFolder/view/"; + assertEquals(expected, UrlUtils.toViewBaseUrl(folderJob, "")); + } + + @Test(expected = NullPointerException.class) + public void testToViewBaseUrl_NullViewName() { + final String fpath = "http://localhost/jobs/someFolder"; + final FolderJob folderJob = new FolderJob("someFolder", fpath); + UrlUtils.toViewBaseUrl(folderJob, null); + } + + + @Test + public void testToFullJobPath_JobNameOnly() { + assertEquals("someJob", UrlUtils.toFullJobPath("someJob")); + } + + + @Test + public void testToFullJobPath_JobNameWithSingleFolder() { + final String expected = "someFolder/job/someJob"; + assertEquals(expected, UrlUtils.toFullJobPath("someFolder/someJob")); + } + + @Test + public void testToFullJobPath_JobNameWithMultipleFolders() { + final String expected = "someFolder1/job/someFolder2/job/someJob"; + assertEquals(expected, UrlUtils.toFullJobPath("someFolder1/someFolder2/someJob")); + } + + @Test(expected = NullPointerException.class) + public void testToFullJobPath_NullJobName() { + UrlUtils.toFullJobPath(null); + } + + + @Test + public void testToFullJobPath_EmptyJobName() { + assertEquals("", UrlUtils.toFullJobPath("")); + } + + + @Test + public void testJoin_EmptyBothPaths() { + assertEquals("", UrlUtils.join("", "")); + } + + @Test + public void testJoin_SlashesOnly() { + assertEquals("/", UrlUtils.join("/", "/")); + } + + @Test + public void testJoin_EmptyPath2() { + assertEquals("1/2/3", UrlUtils.join("1/2/3", "")); + } + + @Test + public void testJoin_EmptyPath1() { + assertEquals("4/5/6", UrlUtils.join("", "4/5/6")); + } + + @Test + public void testJoin_NoTrailingLeadingSlashes() { + assertEquals("1/2/3/4/5/6", UrlUtils.join("1/2/3", "4/5/6")); + + } + + @Test + public void testJoin_TrailingLeadingSlashes() { + assertEquals("/1/2/3/4/5/6/", UrlUtils.join("/1/2/3/", "/4/5/6/")); + } + + @Test + public void testJoin_Path1Trailing_Path2NoLeading() { + assertEquals("/1/2/3/4/5/6/", UrlUtils.join("/1/2/3/", "4/5/6/")); + } + + @Test + public void testJoin_Path1NoTrailing_Path2Leading() { + assertEquals("/1/2/3/4/5/6/", UrlUtils.join("/1/2/3", "/4/5/6/")); + } + + + + + + @Test(expected = NullPointerException.class) + public void testJoin_NullPath1() { + UrlUtils.join(null, "4/5/6"); + } + + @Test(expected = NullPointerException.class) + public void testJoin_NullPath2() { + UrlUtils.join("1/2/3", null); + } + + + @Test + public void testToQueryUri_WithoutQuery() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toJsonApiUri(new URI(suri), "jenkins", "job/somejob"); + final String expected = "http://localhost/jenkins/job/somejob/api/json"; + assertEquals(expected, uri.toString()); + } + + @Test + public void testToQueryUri_EmptyContext() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toJsonApiUri(new URI(suri), "", "job/somejob"); + final String expected = "http://localhost/job/somejob/api/json"; + assertEquals(expected, uri.toString()); + } + + @Test + public void testToQueryUri_EmptyPathAndContext() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toJsonApiUri(new URI(suri), "", ""); + final String expected = "http://localhost/api/json"; + assertEquals(expected, uri.toString()); + } + + @Test(expected = NullPointerException.class) + public void testToQueryUri_NullUri() throws Exception { + UrlUtils.toJsonApiUri(null, "jenkins", "job/somejob"); + } + + + @Test(expected = NullPointerException.class) + public void testToQueryUri_NullPath() throws Exception { + UrlUtils.toJsonApiUri(new URI("http://localhost/jenkins"), "jenkins", null); + } + + @Test(expected = NullPointerException.class) + public void testToQueryUri_NullContext() throws Exception { + UrlUtils.toJsonApiUri(new URI("http://localhost/jenkins"), null, "job/ajob"); + } + + @Test + public void testToQueryUri_EmptyPath() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toJsonApiUri(new URI(suri), "jenkins", ""); + final String expected = "http://localhost/jenkins/api/json"; + assertEquals(expected, uri.toString()); + } + + @Test + public void testToQueryUri_UpperCase() throws Exception { + final String suri = "HTTP://localhost/jenkins"; + final URI uri = UrlUtils.toJsonApiUri(new URI(suri), "jenkins", "job/somejob"); + final String expected = "HTTP://localhost/jenkins/job/somejob/api/json"; + assertEquals(expected, uri.toString()); + } + + + @Test + public void testToQueryUri_WithQuery() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toJsonApiUri(new URI(suri), "jenkins", "job/somejob?pretty=true"); + final String expected = "http://localhost/jenkins/job/somejob/api/json?pretty=true"; + assertEquals(expected, uri.toString()); + } + + + + @Test + public void testToQueryUri_PathContainsSchemeAndContext() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toJsonApiUri(new URI(suri), "jenkins", "http://localhost/jenkins/job/somejob"); + final String expected = "http://localhost/jenkins/job/somejob/api/json"; + assertEquals(expected, uri.toString()); + } + + + @Test + public void testToNoQueryUri_PathContainsSchemeAndContext() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toNoApiUri(new URI(suri), "jenkins", "http://localhost/jenkins/job/somejob"); + final String expected = "http://localhost/jenkins/job/somejob"; + assertEquals(expected, uri.toString()); + } + + + @Test + public void testToNoQueryUri_UpperCase() throws Exception { + final String suri = "HTTP://localhost/jenkins"; + final URI uri = UrlUtils.toNoApiUri(new URI(suri), "jenkins", "job/somejob"); + final String expected = "HTTP://localhost/jenkins/job/somejob"; + assertEquals(expected, uri.toString()); + } + + + @Test + public void testToNoQueryUri_EmptyPath() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toNoApiUri(new URI(suri), "jenkins", ""); + final String expected = "http://localhost/jenkins"; + assertEquals(expected, uri.toString()); + } + + + @Test + public void testToNoQueryUri_EmptyContext() throws Exception { + final String suri = "http://localhost/jenkins"; + final URI uri = UrlUtils.toNoApiUri(new URI(suri), "", "job/somejob"); + final String expected = "http://localhost/job/somejob"; + assertEquals(expected, uri.toString()); + } + + + @Test(expected = NullPointerException.class) + public void testToNoQueryUri_NullContext() throws Exception { + UrlUtils.toNoApiUri(new URI("http://localhost/jenkins"), null, "job/ajob"); + } + +} \ No newline at end of file From c4c8c4b89d17b882d68d85b356bf4bda414eb472 Mon Sep 17 00:00:00 2001 From: Dell Green Date: Wed, 11 Oct 2017 14:43:52 +0100 Subject: [PATCH 06/68] Fixed #298 o Added closeable support to JenkinsServer and JenkinsHttpClient so as to be able to clean up resources when instances no longer required. --- ReleaseNotes.md | 7 ++++++ .../com/offbytwo/jenkins/JenkinsServer.java | 15 ++++++++++- .../jenkins/client/JenkinsHttpClient.java | 25 ++++++++++++++++++- .../offbytwo/jenkins/JenkinsServerTest.java | 15 +++++++++++ .../jenkins/client/JenkinsHttpClientTest.java | 10 ++++++++ .../jenkins/integration/JenkinsServerIT.java | 22 ++++++++++++++++ 6 files changed, 92 insertions(+), 2 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 2d3ad6d6..94243f29 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,13 @@ ## Release 0.3.8 (NOT RELEASED YET) + + * [Fixed Issue 298][issue-298] + + Added Closeable support to JenkinsServer and JenkinsHttpClient so that + underlying resources can be cleaned up when instances no longer required + + * [JENKINS-46472](https://issues.jenkins-ci.org/browse/JENKINS-46472) Added ability to modify offline cause for offline computers. diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java index 0a6f79a4..6f707824 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java @@ -43,11 +43,12 @@ import com.offbytwo.jenkins.model.QueueItem; import com.offbytwo.jenkins.model.QueueReference; import com.offbytwo.jenkins.model.View; +import java.io.Closeable; /** * The main starting point for interacting with a Jenkins server. */ -public class JenkinsServer { +public class JenkinsServer implements Closeable { private final Logger LOGGER = LoggerFactory.getLogger(getClass()); private final JenkinsHttpClient client; @@ -882,6 +883,18 @@ public void renameJob(FolderJob folder, String oldJobName, String newJobName, Bo + "/doRename?newName=" + EncodingUtils.encodeParam(newJobName), crumbFlag); } + + + + /** + * 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(); + } } 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 index 37414993..ce7428c8 100755 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java @@ -49,11 +49,12 @@ 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 java.io.Closeable; import static org.apache.commons.lang.StringUtils.isNotBlank; //import com.offbytwo.jenkins.client.util.HttpResponseContentExtractor; -public class JenkinsHttpClient { +public class JenkinsHttpClient implements Closeable { private final Logger LOGGER = LoggerFactory.getLogger(getClass()); private URI uri; @@ -498,7 +499,27 @@ public boolean isJenkinsVersionSet() { return !EMPTY_VERSION.equals( this.jenkinsVersion ); } + + + + /** + * Closes underlying resources. + * Any I/O errors whilst closing are logged with debug log level + * Closed instances should no longer be used + * Closing an already closed instance has no side effects + */ + @Override + public void close() { + try { + client.close(); + } catch (final IOException ex) { + LOGGER.debug("I/O exception closing client", ex); + } + } + + + private void releaseConnection(HttpRequestBase httpRequestBase) { httpRequestBase.releaseConnection(); } @@ -524,4 +545,6 @@ protected HttpContext getLocalContext() { protected void setLocalContext(HttpContext localContext) { this.localContext = localContext; } + + } diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java index 444d6d3b..e9853b30 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java @@ -32,6 +32,7 @@ import com.offbytwo.jenkins.model.JobWithDetails; import com.offbytwo.jenkins.model.MainView; import com.offbytwo.jenkins.model.View; +import java.net.URI; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -328,6 +329,20 @@ public void getVersionShouldNotFailWithNPE() } + + @Test(expected=IllegalStateException.class) + public void testClose() throws Exception { + final String uri = "http://localhost/jenkins"; + JenkinsServer srv = new JenkinsServer(new URI(uri)); + srv.close(); + srv.close(); //check multiple calls yield no errors + srv.getComputers(); + } + + + + + private void shouldGetFolderJobs(String... jobNames) throws IOException { // given String path = "http://localhost/jobs/someFolder/"; diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java index a55e0560..b4a121d6 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java @@ -51,6 +51,16 @@ public void testGet_String() throws Exception { final String s = jclient.get("job/someJob"); assertEquals("someJson", s); } + + + + @Test(expected=IllegalStateException.class) + public void testClose() throws Exception { + final JenkinsHttpClient jclient = new JenkinsHttpClient(new URI(URI)); + jclient.close(); + jclient.close(); //check multiple calls yield no errors + jclient.get("job/someJob"); + } } \ No newline at end of file diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/JenkinsServerIT.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/JenkinsServerIT.java index 59100302..d7f19a10 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/JenkinsServerIT.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/JenkinsServerIT.java @@ -183,4 +183,26 @@ public void testUpdateJob() throws Exception { String confirmXml = server.getJobXml(JENKINS_TEST_JOB); assertTrue(confirmXml.contains(description)); } + + + @Test(expected=IllegalStateException.class) + public void testClose_ReuseAfterClosed() throws Exception { + final FreeStyleProject proj = jenkinsRule.getInstance().createProject( + FreeStyleProject.class, JENKINS_TEST_JOB); + final Map jobs = server.getJobs(); + assertNotNull(jobs.get(proj.getName())); + server.close(); + server.getJobs(); + } + + + @Test + public void testClose_CloseMultipleTimes() throws Exception { + final FreeStyleProject proj = jenkinsRule.getInstance().createProject( + FreeStyleProject.class, JENKINS_TEST_JOB); + final Map jobs = server.getJobs(); + assertNotNull(jobs.get(proj.getName())); + server.close(); + server.close(); + } } From bf35f47d46474e4444121c96c6c50fc8ee08a505 Mon Sep 17 00:00:00 2001 From: Dell Green Date: Fri, 13 Oct 2017 11:39:37 +0100 Subject: [PATCH 07/68] Fixed #301 o Decoupled JenkinsServer and JenkinsHttpClient by extracting JenkinsHttpClient public methods into public interface --- ReleaseNotes.md | 7 + .../com/offbytwo/jenkins/JenkinsServer.java | 8 +- .../jenkins/client/JenkinsHttpClient.java | 228 +++++++----------- .../jenkins/client/JenkinsHttpConnection.java | 214 ++++++++++++++++ .../com/offbytwo/jenkins/model/BaseModel.java | 26 +- .../offbytwo/jenkins/JenkinsServerTest.java | 3 +- .../jenkins/client/JenkinsHttpClientTest.java | 4 +- .../jenkins/model/BuildWithDetailsTest.java | 3 +- 8 files changed, 344 insertions(+), 149 deletions(-) create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpConnection.java diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 94243f29..4be5026d 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -3,6 +3,13 @@ ## Release 0.3.8 (NOT RELEASED YET) + * [Fixed Issue 301][issue-301] + + Decoupled JenkinsServer and JenkinsHttpClient by extracting JenkinsHttpClient + methods into public interface so that different implementations can be plugged + into JenkinsServer if required + + * [Fixed Issue 298][issue-298] Added Closeable support to JenkinsServer and JenkinsHttpClient so that diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java index 6f707824..87f5a0b0 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java @@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.offbytwo.jenkins.client.JenkinsHttpClient; +import com.offbytwo.jenkins.client.JenkinsHttpConnection; import com.offbytwo.jenkins.client.util.EncodingUtils; import com.offbytwo.jenkins.client.util.UrlUtils; import com.offbytwo.jenkins.helper.JenkinsVersion; @@ -51,7 +52,10 @@ public class JenkinsServer implements Closeable { private final Logger LOGGER = LoggerFactory.getLogger(getClass()); - private final JenkinsHttpClient client; + /** + * The transport client instance to use. + */ + private final JenkinsHttpConnection client; /** * Create a new Jenkins server reference given only the server address @@ -80,7 +84,7 @@ public JenkinsServer(URI serverUri, String username, String passwordOrToken) { * * @param client Specialized client to use. */ - public JenkinsServer(JenkinsHttpClient client) { + public JenkinsServer(final JenkinsHttpConnection client) { this.client = client; } 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 index ce7428c8..31c64141 100755 --- 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,7 +3,6 @@ * * Distributed under the MIT license: http://opensource.org/licenses/MIT */ - package com.offbytwo.jenkins.client; import com.fasterxml.jackson.databind.ObjectMapper; @@ -49,12 +48,10 @@ 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 java.io.Closeable; import static org.apache.commons.lang.StringUtils.isNotBlank; -//import com.offbytwo.jenkins.client.util.HttpResponseContentExtractor; +public class JenkinsHttpClient implements JenkinsHttpConnection { -public class JenkinsHttpClient implements Closeable { private final Logger LOGGER = LoggerFactory.getLogger(getClass()); private URI uri; @@ -69,7 +66,7 @@ public class JenkinsHttpClient implements Closeable { private String jenkinsVersion; public final static String EMPTY_VERSION = "UNKNOWN"; - + /** * Create an unauthenticated Jenkins HTTP client * @@ -137,14 +134,9 @@ public JenkinsHttpClient(URI uri, HttpClientBuilder builder, String username, St } /** - * 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 type of the response - * @return an instance of the supplied class - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public T get(String path, Class cls) throws IOException { HttpGet getMethod = new HttpGet(UrlUtils.toJsonApiUri(uri, context, path)); @@ -160,13 +152,9 @@ public T get(String path, Class cls) throws IOException } /** - * Perform a GET request and parse the response and return a simple string - * of the content - * - * @param path path to request, can be relative or absolute - * @return the entity text - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public String get(String path) throws IOException { HttpGet getMethod = new HttpGet(UrlUtils.toJsonApiUri(uri, context, path)); HttpResponse response = client.execute(getMethod, localContext); @@ -184,14 +172,9 @@ public String get(String path) throws IOException { } /** - * Perform a GET request and parse the response to the given class, logging - * any IOException that is thrown rather than propagating it. - * - * @param path path to request, can be relative or absolute - * @param cls class of the response - * @param type of the response - * @return an instance of the supplied class + * {@inheritDoc} */ + @Override public T getQuietly(String path, Class cls) { T value; try { @@ -205,12 +188,9 @@ public T getQuietly(String path, Class cls) { } /** - * Perform a GET request and return the response as InputStream - * - * @param path path to request, can be relative or absolute - * @return the response stream - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public InputStream getFile(URI path) throws IOException { HttpGet getMethod = new HttpGet(path); HttpResponse response = client.execute(getMethod, localContext); @@ -219,22 +199,18 @@ public InputStream getFile(URI path) throws IOException { return new RequestReleasingInputStream(response.getEntity().getContent(), getMethod); } + /** + * {@inheritDoc} + */ + @Override public R post(String path, D data, Class cls) throws IOException { return post(path, data, cls, true); } /** - * Perform a POST request and parse the response to the given class - * - * @param path path to request, can be relative or absolute - * @param data data to post - * @param cls class of the response - * @param type of the response - * @param type of the data - * @param crumbFlag true / false. - * @return an instance of the supplied class - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public R post(String path, D data, Class cls, boolean crumbFlag) throws IOException { HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(uri, context, path)); if (crumbFlag == true) { @@ -275,23 +251,9 @@ public R post(String path, D data, Class cls, boolea } /** - * Perform a POST request using form url encoding. - * - * This method was added for the purposes of creating folders, but may be - useful for other API calls as well. - - Unlike post and post_xml, the path is *not* modified by adding - "/toJsonApiUri/json". Additionally, the params in data are provided as both - request parameters including a json parameter, *and* in the - JSON-formatted StringEntity, because this is what the folder creation - call required. It is unclear if any other jenkins APIs operate in this - fashion. - * - * @param path path to request, can be relative or absolute - * @param data data to post - * @param crumbFlag true / false. - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public void post_form(String path, Map data, boolean crumbFlag) throws IOException { HttpPost request; if (data != null) { @@ -329,18 +291,10 @@ public void post_form(String path, Map data, boolean crumbFlag) } } - /** - * Perform a POST request using form url encoding and return HttpResponse object - * This method is not performing validation and can be used for more generic queries to jenkins. - * - * @param path - * path to request, can be relative or absolute - * @param data - * data to post - * @throws IOException, - * HttpResponseException + * {@inheritDoc} */ + @Override public HttpResponse post_form_with_result(String path, List data, boolean crumbFlag) throws IOException { HttpPost request; if (data != null) { @@ -363,18 +317,17 @@ public HttpResponse post_form_with_result(String path, List data, } /** - * Perform a POST request of XML (instead of using json mapper) and return a - * string rendering of the response entity. - * - * @param path path to request, can be relative or absolute - * @param xml_data data data to post - * @return A string containing the xml response (if present) - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public String post_xml(String path, String xml_data) throws IOException { return post_xml(path, xml_data, true); } + /** + * {@inheritDoc} + */ + @Override public String post_xml(String path, String xml_data, boolean crumbFlag) throws IOException { HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(uri, context, path)); if (crumbFlag == true) { @@ -399,28 +352,17 @@ public String post_xml(String path, String xml_data, boolean crumbFlag) throws I } /** - * Post a text entity to the given URL using the default content type - * - * @param path The path. - * @param textData data. - * @param crumbFlag true/false. - * @return resulting response - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public String post_text(String path, String textData, boolean crumbFlag) throws IOException { return post_text(path, textData, ContentType.DEFAULT_TEXT, crumbFlag); } /** - * Post a text entity to the given URL with the given content type - * - * @param path The path. - * @param textData The data. - * @param contentType {@link ContentType} - * @param crumbFlag true or false. - * @return resulting response - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public String post_text(String path, String textData, ContentType contentType, boolean crumbFlag) throws IOException { HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(uri, context, path)); @@ -446,67 +388,41 @@ public String post_text(String path, String textData, ContentType contentType, b } /** - * Perform POST request that takes no parameters and returns no response - * - * @param path path to request - * @throws IOException in case of an error. + * {@inheritDoc} */ + @Override public void post(String path) throws IOException { post(path, null, null, false); } + /** + * {@inheritDoc} + */ + @Override public void post(String path, boolean crumbFlag) throws IOException { post(path, null, null, crumbFlag); } - - - - - - - private T objectFromResponse(Class cls, HttpResponse response) throws IOException { - InputStream content = response.getEntity().getContent(); - byte[] bytes = ByteStreams.toByteArray(content); - T result = mapper.readValue(bytes, cls); - // TODO: original: - // T result = mapper.readValue(content, cls); - result.setClient(this); - return result; - } - - private ObjectMapper getDefaultMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.disable(FAIL_ON_UNKNOWN_PROPERTIES); - return mapper; - } - /** - * @return the version string. + * {@inheritDoc} */ + @Override public String getJenkinsVersion() { return this.jenkinsVersion; } /** - * Check to see if the jenkins version has been set - * to something different than the initialization value - * from the constructor. This means there has never been made - * a communication with the Jenkins server. - * @return true if jenkinsVersion has been set by communication, false otherwise. + * {@inheritDoc} */ + @Override public boolean isJenkinsVersionSet() { - return !EMPTY_VERSION.equals( this.jenkinsVersion ); + return !EMPTY_VERSION.equals(this.jenkinsVersion); } - - - - + /** - * Closes underlying resources. - * Any I/O errors whilst closing are logged with debug log level - * Closed instances should no longer be used - * Closing an already closed instance has no side effects + * Closes underlying resources. Any I/O errors whilst closing are logged + * with debug log level Closed instances should no longer be used Closing an + * already closed instance has no side effects */ @Override public void close() { @@ -514,17 +430,20 @@ public void close() { client.close(); } catch (final IOException ex) { LOGGER.debug("I/O exception closing client", ex); - } + } } - - - private void releaseConnection(HttpRequestBase httpRequestBase) { - httpRequestBase.releaseConnection(); - } - - protected static HttpClientBuilder addAuthentication(HttpClientBuilder builder, URI uri, String username, + /** + * Add authentication to supplied builder. + * @param builder the builder to configure + * @param uri the server URI + * @param username the username + * @param password the password + * @return the passed in builder + */ + protected static HttpClientBuilder addAuthentication(final HttpClientBuilder builder, + final URI uri, final String username, String password) { if (isNotBlank(username)) { CredentialsProvider provider = new BasicCredentialsProvider(); @@ -538,13 +457,46 @@ protected static HttpClientBuilder addAuthentication(HttpClientBuilder builder, return builder; } + + /** + * Get the local context. + * @return context + */ protected HttpContext getLocalContext() { return localContext; } - protected void setLocalContext(HttpContext localContext) { + + /** + * Set the local context. + * @param localContext the context + */ + protected void setLocalContext(final HttpContext localContext) { this.localContext = localContext; } + + + + private T objectFromResponse(Class cls, HttpResponse response) throws IOException { + InputStream content = response.getEntity().getContent(); + byte[] bytes = ByteStreams.toByteArray(content); + T result = mapper.readValue(bytes, cls); + // TODO: original: + // T result = mapper.readValue(content, cls); + result.setClient(this); + return result; + } + + private ObjectMapper getDefaultMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.disable(FAIL_ON_UNKNOWN_PROPERTIES); + return mapper; + } + + private void releaseConnection(HttpRequestBase httpRequestBase) { + httpRequestBase.releaseConnection(); + } + } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpConnection.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpConnection.java new file mode 100644 index 00000000..5e1997fa --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpConnection.java @@ -0,0 +1,214 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.offbytwo.jenkins.client; + +import com.offbytwo.jenkins.model.BaseModel; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.List; +import java.util.Map; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.entity.ContentType; + +/** + * + * @author Dell Green + */ +public interface JenkinsHttpConnection extends Closeable { + + + + /** + * {@inheritDoc} + */ + @Override + public void close(); + + + /** + * 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 type of the response + * @return an instance of the supplied class + * @throws IOException in case of an error. + */ + T get(String path, Class cls) throws IOException; + + /** + * Perform a GET request and parse the response and return a simple string + * of the content + * + * @param path path to request, can be relative or absolute + * @return the entity text + * @throws IOException in case of an error. + */ + String get(String path) throws IOException; + + /** + * Perform a GET request and return the response as InputStream + * + * @param path path to request, can be relative or absolute + * @return the response stream + * @throws IOException in case of an error. + */ + InputStream getFile(URI path) throws IOException; + + /** + * Perform a GET request and parse the response to the given class, logging + * any IOException that is thrown rather than propagating it. + * + * @param path path to request, can be relative or absolute + * @param cls class of the response + * @param type of the response + * @return an instance of the supplied class + */ + T getQuietly(String path, Class cls); + + /** + * Check to see if the Jenkins version has been set to something different + * than the initialisation value from the constructor. This means there has + * never been made a communication with the Jenkins server. + * @return true if jenkinsVersion has been set by communication, false + * otherwise. + */ + boolean isJenkinsVersionSet(); + + + /** + * Perform a POST request and parse the response to the given class + * + * @param path path to request, can be relative or absolute + * @param data data to post + * @param cls class of the response + * @param type of the response + * @param type of the data + * @return an instance of the supplied class + * @throws IOException in case of an error. + */ + R post(String path, D data, Class cls) throws IOException; + + /** + * Perform a POST request and parse the response to the given class + * + * @param path path to request, can be relative or absolute + * @param data data to post + * @param cls class of the response + * @param type of the response + * @param type of the data + * @param crumbFlag true / false. + * @return an instance of the supplied class + * @throws IOException in case of an error. + */ + R post(String path, D data, Class cls, boolean crumbFlag) throws IOException; + + /** + * Perform POST request that takes no parameters and returns no response + * + * @param path path to request + * @throws IOException in case of an error. + */ + void post(String path) throws IOException; + + + /** + * Perform POST request that takes no parameters and returns no response + * + * @param path path to request + * @param crumbFlag true / false. + * @throws IOException in case of an error. + */ + void post(String path, boolean crumbFlag) throws IOException; + + /** + * Perform a POST request using form url encoding. + * + * This method was added for the purposes of creating folders, but may be + * useful for other API calls as well. Unlike post and post_xml, the path is + * *not* modified by adding "/toJsonApiUri/json". Additionally, the params + * in data are provided as both request parameters including a json + * parameter, *and* in the JSON-formatted StringEntity, because this is what + * the folder creation call required. It is unclear if any other jenkins + * APIs operate in this fashion. + * + * @param path path to request, can be relative or absolute + * @param data data to post + * @param crumbFlag true / false. + * @throws IOException in case of an error. + */ + void post_form(String path, Map data, boolean crumbFlag) throws IOException; + + /** + * Perform a POST request using form url encoding and return HttpResponse + * object This method is not performing validation and can be used for more + * generic queries to jenkins. + * + * @param path path to request, can be relative or absolute + * @param data data to post + * @param crumbFlag true / false. + * @return resulting response + * @throws IOException, HttpResponseException + */ + HttpResponse post_form_with_result(String path, List data, boolean crumbFlag) throws IOException; + + /** + * Post a text entity to the given URL using the default content type + * + * @param path The path. + * @param textData data. + * @param crumbFlag true/false. + * @return resulting response + * @throws IOException in case of an error. + */ + String post_text(String path, String textData, boolean crumbFlag) throws IOException; + + /** + * Post a text entity to the given URL with the given content type + * + * @param path The path. + * @param textData The data. + * @param contentType {@link ContentType} + * @param crumbFlag true or false. + * @return resulting response + * @throws IOException in case of an error. + */ + String post_text(String path, String textData, ContentType contentType, boolean crumbFlag) throws IOException; + + /** + * Perform a POST request of XML (instead of using json mapper) and return a + * string rendering of the response entity. + * + * @param path path to request, can be relative or absolute + * @param xml_data data data to post + * @return A string containing the xml response (if present) + * @throws IOException in case of an error. + */ + String post_xml(String path, String xml_data) throws IOException; + + /** + * Perform a POST request of XML (instead of using json mapper) and return a + * string rendering of the response entity. + * + * @param path path to request, can be relative or absolute + * @param xml_data data data to post + * @param crumbFlag true or false. + * @return A string containing the xml response (if present) + * @throws IOException in case of an error. + */ + String post_xml(String path, String xml_data, boolean crumbFlag) throws IOException; + + /** + * Get the Jenkins server version. + * + * @return the version string + */ + String getJenkinsVersion(); + +} diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java index dd473ee8..90d7f793 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java @@ -6,28 +6,44 @@ package com.offbytwo.jenkins.model; -import com.offbytwo.jenkins.client.JenkinsHttpClient; +import com.offbytwo.jenkins.client.JenkinsHttpConnection; /** * The base model. - * */ public class BaseModel { + /** + * The class. + */ private String _class; + + /** + * Get the class. + * @return class + */ public String get_class() { return _class; } //TODO: We should make this private - protected JenkinsHttpClient client; + protected JenkinsHttpConnection client; - public JenkinsHttpClient getClient() { + + /** + * Get the HTTP client. + * @return client + */ + public JenkinsHttpConnection getClient() { return client; } - public void setClient(JenkinsHttpClient client) { + /** + * Set the HTTP client. + * @param client + */ + public void setClient(final JenkinsHttpConnection client) { this.client = client; } } diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java index e9853b30..9e9d50aa 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java @@ -27,6 +27,7 @@ import com.google.common.base.Optional; import com.offbytwo.jenkins.client.JenkinsHttpClient; +import com.offbytwo.jenkins.client.JenkinsHttpConnection; import com.offbytwo.jenkins.model.FolderJob; import com.offbytwo.jenkins.model.Job; import com.offbytwo.jenkins.model.JobWithDetails; @@ -41,7 +42,7 @@ public class JenkinsServerTest extends BaseUnitTest { - private JenkinsHttpClient client = mock(JenkinsHttpClient.class); + private JenkinsHttpConnection client = mock(JenkinsHttpClient.class); private JenkinsServer server = new JenkinsServer(client); private MainView mainView = new MainView(new Job("Hello", "http://localhost/job/Hello/")); diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java index b4a121d6..80f3ba38 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/JenkinsHttpClientTest.java @@ -47,7 +47,7 @@ public void testGet_String() throws Exception { given(statusLine.getStatusCode()).willReturn(HttpStatus.SC_OK); given(response.getEntity()).willReturn(entity); given(entity.getContent()).willReturn(new ByteArrayInputStream("someJson".getBytes())); - final JenkinsHttpClient jclient = new JenkinsHttpClient(new URI(URI), client); + final JenkinsHttpConnection jclient = new JenkinsHttpClient(new URI(URI), client); final String s = jclient.get("job/someJob"); assertEquals("someJson", s); } @@ -56,7 +56,7 @@ public void testGet_String() throws Exception { @Test(expected=IllegalStateException.class) public void testClose() throws Exception { - final JenkinsHttpClient jclient = new JenkinsHttpClient(new URI(URI)); + final JenkinsHttpConnection jclient = new JenkinsHttpClient(new URI(URI)); jclient.close(); jclient.close(); //check multiple calls yield no errors jclient.get("job/someJob"); diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/model/BuildWithDetailsTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/model/BuildWithDetailsTest.java index af25f266..83ddd07b 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/model/BuildWithDetailsTest.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/model/BuildWithDetailsTest.java @@ -2,6 +2,7 @@ import com.offbytwo.jenkins.BaseUnitTest; import com.offbytwo.jenkins.client.JenkinsHttpClient; +import com.offbytwo.jenkins.client.JenkinsHttpConnection; import com.offbytwo.jenkins.helper.BuildConsoleStreamListener; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; @@ -24,7 +25,7 @@ */ public class BuildWithDetailsTest extends BaseUnitTest { - private JenkinsHttpClient client; + private JenkinsHttpConnection client; private BuildWithDetails buildWithDetails; @Before From f9ed73c2427cc16dd0dddfc93771f506a8b408fc Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sat, 2 Dec 2017 10:56:59 +0100 Subject: [PATCH 08/68] Upgraded Test NG from 6.8.21 to 6.13 Upgraded maven-compiler-plugin from 3.6.0 to 3.7.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index cb1291fb..03648a1c 100644 --- a/pom.xml +++ b/pom.xml @@ -158,7 +158,7 @@ org.testng testng - 6.8.21 + 6.13 test @@ -277,7 +277,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.6.0 + 3.7.0 + + org.apache.maven.plugins + maven-javadoc-plugin + + + + javadoc-no-fork + aggregate-no-fork + + + + From 95a33d4f4b0a4cce452900a8da8b4cd63607a599 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Tue, 2 Apr 2019 21:13:36 +0200 Subject: [PATCH 39/68] Fixed #400 - Upgrade assertj-core to 3.12.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0bec88bc..d43129bd 100644 --- a/pom.xml +++ b/pom.xml @@ -198,7 +198,7 @@ org.assertj assertj-core - 3.11.1 + 3.12.2 test From 62730cb90e972ba8033adc4cecc69a953239d7e7 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Tue, 2 Apr 2019 21:25:45 +0200 Subject: [PATCH 40/68] Upgrade ReleaseNotes. --- ReleaseNotes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 0a59bcdc..e2416641 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,10 @@ ## Release 0.3.9 (NOT RELEASED YET) + * [Fixed Issue 400][issue-400] + + Upgrade assertj-core. + * [Fixed Issue 399][issue-399] Upgrade Maven Plugins @@ -1095,6 +1099,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-394]: https://github.com/jenkinsci/java-client-api/issues/394 [issue-396]: https://github.com/jenkinsci/java-client-api/issues/396 [issue-399]: https://github.com/jenkinsci/java-client-api/issues/399 +[issue-400]: https://github.com/jenkinsci/java-client-api/issues/400 [pull-123]: https://github.com/jenkinsci/java-client-api/pull/123 [pull-149]: https://github.com/jenkinsci/java-client-api/pull/149 [pull-158]: https://github.com/jenkinsci/java-client-api/pull/158 From 3251301a917be0ee56dfa2e34020b01abb5e0ef4 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Tue, 2 Apr 2019 22:06:30 +0200 Subject: [PATCH 41/68] Fixed #401 - Upgrade JUnit to 4.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d43129bd..dacee82e 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ 1.644 - 4.11 + 4.12 1.9.5 2.4 1.4.7-jenkins-1 From c033dff4a4af03e51019dd18169d0b538049c6a8 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Tue, 2 Apr 2019 22:15:18 +0200 Subject: [PATCH 42/68] Updated ReleaseNotes. --- ReleaseNotes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index e2416641..38cd3a83 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,10 @@ ## Release 0.3.9 (NOT RELEASED YET) + * [Fixed Issue 401][issue-401] + + Upgrade JUnit + * [Fixed Issue 400][issue-400] Upgrade assertj-core. @@ -1100,6 +1104,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-396]: https://github.com/jenkinsci/java-client-api/issues/396 [issue-399]: https://github.com/jenkinsci/java-client-api/issues/399 [issue-400]: https://github.com/jenkinsci/java-client-api/issues/400 +[issue-401]: https://github.com/jenkinsci/java-client-api/issues/401 [pull-123]: https://github.com/jenkinsci/java-client-api/pull/123 [pull-149]: https://github.com/jenkinsci/java-client-api/pull/149 [pull-158]: https://github.com/jenkinsci/java-client-api/pull/158 From 7a05defea155eee23c7f5dc77300394860b60a68 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Tue, 2 Apr 2019 22:18:19 +0200 Subject: [PATCH 43/68] Fixed #402 - Upgrade httpclient/httpcore/httpmime to 4.5.8 --- ReleaseNotes.md | 5 +++++ pom.xml | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 38cd3a83..45b054d4 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,10 @@ ## Release 0.3.9 (NOT RELEASED YET) + * [Fixed Issue 402][issue-402] + + Upgrade httpclient/httpmine/httpcore. + * [Fixed Issue 401][issue-401] Upgrade JUnit @@ -1105,6 +1109,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-399]: https://github.com/jenkinsci/java-client-api/issues/399 [issue-400]: https://github.com/jenkinsci/java-client-api/issues/400 [issue-401]: https://github.com/jenkinsci/java-client-api/issues/401 +[issue-402]: https://github.com/jenkinsci/java-client-api/issues/402 [pull-123]: https://github.com/jenkinsci/java-client-api/pull/123 [pull-149]: https://github.com/jenkinsci/java-client-api/pull/149 [pull-158]: https://github.com/jenkinsci/java-client-api/pull/158 diff --git a/pom.xml b/pom.xml index dacee82e..51db9575 100644 --- a/pom.xml +++ b/pom.xml @@ -60,9 +60,9 @@ 3.8.1 17.0 2.4 - 4.3.6 - 4.3.3 - 4.3.6 + 4.5.8 + 4.4.11 + 4.5.8 2.9.6 From caf969c801f000d611bd5bc7e318bf71facf9416 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Fri, 5 Apr 2019 18:23:52 +0200 Subject: [PATCH 44/68] Fixed link issues in ReleaseNotes. --- ReleaseNotes.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 45b054d4..66f5364e 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1106,6 +1106,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-301]: https://github.com/jenkinsci/java-client-api/issues/301 [issue-394]: https://github.com/jenkinsci/java-client-api/issues/394 [issue-396]: https://github.com/jenkinsci/java-client-api/issues/396 +[issue-397]: https://github.com/jenkinsci/java-client-api/issues/397 [issue-399]: https://github.com/jenkinsci/java-client-api/issues/399 [issue-400]: https://github.com/jenkinsci/java-client-api/issues/400 [issue-401]: https://github.com/jenkinsci/java-client-api/issues/401 @@ -1127,5 +1128,5 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [jissue-38787]: https://issues.jenkins-ci.org/browse/JENKINS-38787 [jissue-38816]: https://issues.jenkins-ci.org/browse/JENKINS-38816 [jissue-38823]: https://issues.jenkins-ci.org/browse/JENKINS-38823 -[jissue-46445]: https://issues.jenkins-ci.org/browse/JENKINS-46445) -[jissue-46472]: https://issues.jenkins-ci.org/browse/JENKINS-46472) +[jissue-46445]: https://issues.jenkins-ci.org/browse/JENKINS-46445 +[jissue-46472]: https://issues.jenkins-ci.org/browse/JENKINS-46472 From f164cf7f6c865a01e3cc3d1a2fe09ffbf9a4b7a5 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sat, 6 Apr 2019 15:08:32 +0200 Subject: [PATCH 45/68] Cleaned up ReleaseNotes. --- ReleaseNotes.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 66f5364e..f54d4788 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -34,8 +34,6 @@ Add the crumbFlag as the 2nd parameter of getConsoleOutputText method -https://github.com/jenkinsci/java-client-api/pull/386 - ## Release 0.3.8 * [Fixed Issue 289][issue-289] From 23e120ec112c4c696bea144c63b2f56d5a4e3543 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sun, 7 Apr 2019 12:51:06 +0200 Subject: [PATCH 46/68] Fixed #405 - Update jackson-databind to 2.9.8 --- ReleaseNotes.md | 11 +++++++++++ pom.xml | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index f54d4788..c142e628 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,16 @@ ## Release 0.3.9 (NOT RELEASED YET) + * [Fixed Issue 405][issue-405] + + * CVE-2018-14718 + * CVE-2018-14719 + * CVE-2018-14720 + * CVE-2018-14721 + * CVE-2018-19360 + * CVE-2018-19361 + * CVE-2018-19362 + * [Fixed Issue 402][issue-402] Upgrade httpclient/httpmine/httpcore. @@ -1109,6 +1119,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-400]: https://github.com/jenkinsci/java-client-api/issues/400 [issue-401]: https://github.com/jenkinsci/java-client-api/issues/401 [issue-402]: https://github.com/jenkinsci/java-client-api/issues/402 +[issue-405]: https://github.com/jenkinsci/java-client-api/issues/405 [pull-123]: https://github.com/jenkinsci/java-client-api/pull/123 [pull-149]: https://github.com/jenkinsci/java-client-api/pull/149 [pull-158]: https://github.com/jenkinsci/java-client-api/pull/158 diff --git a/pom.xml b/pom.xml index 51db9575..481dedff 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 4.5.8 4.4.11 4.5.8 - 2.9.6 + 2.9.8 From 315bb4fb7cad93a970b64c8d24186a1d6b02429a Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Tue, 2 Apr 2019 22:39:24 +0200 Subject: [PATCH 47/68] Fixed #395 - Remove google guava lib - Replaced many things with base JDK8 constructs. - In JDK9 we can improve some more parts. - We do not generat shaded artifact 'stash' anymore. - Upgrade version number based on the change. --- ReleaseNotes.md | 13 ++- jenkins-client-it-docker/pom.xml | 7 +- .../NoExecutorStartedGetJobIT.java | 3 +- .../NoExecutorStartedGetJobXmlIT.java | 4 +- jenkins-client/pom.xml | 35 +------ .../com/offbytwo/jenkins/JenkinsServer.java | 70 ++++++------- .../jenkins/client/JenkinsHttpClient.java | 8 +- .../jenkins/client/util/EncodingUtils.java | 32 +++++- .../jenkins/helper/FunctionalHelper.java | 22 +++++ .../jenkins/model/BuildWithDetails.java | 97 ++++++++----------- .../offbytwo/jenkins/model/ComputerSet.java | 15 +-- .../jenkins/model/ComputerWithDetails.java | 12 +-- .../com/offbytwo/jenkins/model/FolderJob.java | 45 +++++---- .../java/com/offbytwo/jenkins/model/Job.java | 9 +- .../jenkins/model/JobWithDetails.java | 92 +++++++----------- .../com/offbytwo/jenkins/model/MainView.java | 7 +- .../jenkins/model/MavenJobWithDetails.java | 85 +++++++--------- .../java/com/offbytwo/jenkins/FirstTest.java | 56 +++++++++++ .../offbytwo/jenkins/JenkinsServerTest.java | 2 +- .../client/util/EncodingUtilsTest.java | 14 ++- .../jenkins/integration/FolderTestsIT.java | 4 +- .../jenkins/integration/JenkinsServerIT.java | 2 +- pom.xml | 9 +- 23 files changed, 331 insertions(+), 312 deletions(-) create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/helper/FunctionalHelper.java create mode 100644 jenkins-client/src/test/java/com/offbytwo/jenkins/FirstTest.java diff --git a/ReleaseNotes.md b/ReleaseNotes.md index c142e628..7003cd77 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,6 +1,16 @@ # Release Notes -## Release 0.3.9 (NOT RELEASED YET) +## Release 0.4.0 (NOT RELEASED YET) + + * [Fixed Issue 395][issue-395] + + * Remove google guava lib + * Removed also the creation of the shaded artifact `stash` + cause we do not rely on Guava anymore. So you + can use the original artifact directly. + * This results in a bumping of the version + number cause it a change which is breaking + with previous version 0.3.8. * [Fixed Issue 405][issue-405] @@ -1113,6 +1123,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-298]: https://github.com/jenkinsci/java-client-api/issues/298 [issue-301]: https://github.com/jenkinsci/java-client-api/issues/301 [issue-394]: https://github.com/jenkinsci/java-client-api/issues/394 +[issue-395]: https://github.com/jenkinsci/java-client-api/issues/395 [issue-396]: https://github.com/jenkinsci/java-client-api/issues/396 [issue-397]: https://github.com/jenkinsci/java-client-api/issues/397 [issue-399]: https://github.com/jenkinsci/java-client-api/issues/399 diff --git a/jenkins-client-it-docker/pom.xml b/jenkins-client-it-docker/pom.xml index 8f4c7ac7..11e6b485 100644 --- a/jenkins-client-it-docker/pom.xml +++ b/jenkins-client-it-docker/pom.xml @@ -11,7 +11,7 @@ com.offbytwo.jenkins jenkins-client-parent - 0.3.9-SNAPSHOT + 0.4.0-SNAPSHOT jenkins-client-it-docker @@ -43,11 +43,6 @@ assertj-core test - - com.google.guava - guava - test - org.apache.httpcomponents httpclient diff --git a/jenkins-client-it-docker/src/test/java/com/offbytwo/jenkins/integration/NoExecutorStartedGetJobIT.java b/jenkins-client-it-docker/src/test/java/com/offbytwo/jenkins/integration/NoExecutorStartedGetJobIT.java index 279bb40a..35c2aeac 100644 --- a/jenkins-client-it-docker/src/test/java/com/offbytwo/jenkins/integration/NoExecutorStartedGetJobIT.java +++ b/jenkins-client-it-docker/src/test/java/com/offbytwo/jenkins/integration/NoExecutorStartedGetJobIT.java @@ -7,7 +7,6 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import com.google.common.base.Joiner; import com.offbytwo.jenkins.model.Build; import com.offbytwo.jenkins.model.BuildResult; import com.offbytwo.jenkins.model.BuildWithDetails; @@ -50,7 +49,7 @@ private void checkJob(BuildWithDetails details) throws IOException { "Building in workspace /var/jenkins_home/jobs/test/workspace", "[workspace] $ /bin/sh -xe /tmp/hudson2556403647634111927.sh", "+ echo test", "test", "Finished: SUCCESS", "" }; - String expectedOutput = Joiner.on("\r\n").join(expectedOutputLines); + String expectedOutput = String.join("\r\n", expectedOutputLines); // Hint: It looks like the consoleOutputText contains CR+LF String resultingOutput = details.getConsoleOutputText(); assertThat(resultingOutput).isEqualTo(expectedOutput); diff --git a/jenkins-client-it-docker/src/test/java/com/offbytwo/jenkins/integration/NoExecutorStartedGetJobXmlIT.java b/jenkins-client-it-docker/src/test/java/com/offbytwo/jenkins/integration/NoExecutorStartedGetJobXmlIT.java index 451e7585..38a3507a 100644 --- a/jenkins-client-it-docker/src/test/java/com/offbytwo/jenkins/integration/NoExecutorStartedGetJobXmlIT.java +++ b/jenkins-client-it-docker/src/test/java/com/offbytwo/jenkins/integration/NoExecutorStartedGetJobXmlIT.java @@ -7,8 +7,6 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import com.google.common.base.Joiner; - @Test(groups = { Groups.NO_EXECUTOR_GROUP }) public class NoExecutorStartedGetJobXmlIT extends AbstractJenkinsIntegrationCase { @@ -47,7 +45,7 @@ public void beforeMethod() throws IOException { @Test public void getJobXmlShouldReturnTheExpectedConfigXml() { - String expectedXml = Joiner.on("\n").join(CONFIG_XML); + String expectedXml = String.join("\n", CONFIG_XML); assertThat(jobXml).isEqualTo(expectedXml); } diff --git a/jenkins-client/pom.xml b/jenkins-client/pom.xml index 75eb3fc9..ea595a4d 100644 --- a/jenkins-client/pom.xml +++ b/jenkins-client/pom.xml @@ -11,7 +11,7 @@ com.offbytwo.jenkins jenkins-client-parent - 0.3.9-SNAPSHOT + 0.4.0-SNAPSHOT jenkins-client @@ -51,11 +51,6 @@ - - com.google.guava - guava - - org.apache.commons commons-lang3 @@ -127,28 +122,6 @@ org.apache.maven.plugins maven-shade-plugin - - stash - package - - shade - - - - - com.google.guava:guava - - - true - stash - - - com.google.common - com.google.common.jenkins_client_jarjar - - - - httpclient package @@ -164,12 +137,6 @@ true apachehttp - - - com.google.common - com.google.common.jenkins_client_jarjar - - diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java index 8753a1a3..f76da927 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java @@ -8,11 +8,14 @@ import java.io.IOException; import java.net.URI; +import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBException; +import com.offbytwo.jenkins.helper.FunctionalHelper; +import com.offbytwo.jenkins.model.BaseModel; import org.apache.http.HttpStatus; import org.apache.http.client.HttpResponseException; import org.apache.http.entity.ContentType; @@ -20,10 +23,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; import com.offbytwo.jenkins.client.JenkinsHttpClient; import com.offbytwo.jenkins.client.JenkinsHttpConnection; import com.offbytwo.jenkins.client.util.EncodingUtils; @@ -45,6 +44,12 @@ import com.offbytwo.jenkins.model.QueueReference; import com.offbytwo.jenkins.model.View; import java.io.Closeable; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static com.offbytwo.jenkins.helper.FunctionalHelper.SET_CLIENT; +import static java.util.stream.Collectors.toMap; /** * The main starting point for interacting with a Jenkins server. @@ -167,13 +172,10 @@ public Map getJobs(FolderJob folder, String view) throws IOExceptio viewClass = View.class; } List jobs = client.get(path, viewClass).getJobs(); - return Maps.uniqueIndex(jobs, new Function() { - @Override - public String apply(Job job) { - job.setClient(client); - return job.getName(); - } - }); + + return jobs.stream() + .map(SET_CLIENT(this.client)) + .collect(toMap(s -> s.getName(), s -> s)); } /** @@ -198,22 +200,23 @@ public Map getViews(FolderJob folder) throws IOException { // This is much better than using &depth=2 // http://localhost:8080/api/json?pretty&tree=views[name,url,jobs[name,url]] List views = client.get(UrlUtils.toBaseUrl(folder) + "?tree=views[name,url,jobs[name,url]]", MainView.class).getViews(); - return Maps.uniqueIndex(views, new Function() { - @Override - public String apply(View view) { - view.setClient(client); - // TODO: Think about the following? Does there exists a - // simpler/more elegant method? + + //TODO: Think about this Lambda. It's too large? Make it smaller! + return views.stream().map(view -> { + SET_CLIENT(this.client); + + // TODO: Think about the following? Does there exists a simpler/more + // elegant method? for (Job job : view.getJobs()) { - job.setClient(client); + SET_CLIENT(this.client); } - for (View item : view.getViews()) { - item.setClient(client); + for (View viewView : view.getViews()) { + SET_CLIENT(this.client); } - return view.getName(); - } - }); + return view; + }) + .collect(Collectors.toMap(s -> s.getName(), v -> v)); } /** @@ -317,10 +320,9 @@ public Optional getFolderJob(Job job) throws IOException { try { FolderJob folder = client.get(job.getUrl(), FolderJob.class); if (!folder.isFolder()) { - return Optional.absent(); + return Optional.empty(); } folder.setClient(client); - return Optional.of(folder); } catch (HttpResponseException e) { LOGGER.debug("getForlderJob(job={}) status={}", job, e.getStatusCode()); @@ -487,8 +489,12 @@ public void createFolder(FolderJob folder, String jobName) throws IOException { public void createFolder(FolderJob folder, String jobName, Boolean crumbFlag) throws IOException { // https://gist.github.com/stuart-warren/7786892 was slightly helpful // here - ImmutableMap params = ImmutableMap.of("mode", "com.cloudbees.hudson.plugins.folder.Folder", - "name", EncodingUtils.formParameter(jobName), "from", "", "Submit", "OK"); + //TODO: JDK9+: Map.of(...) + Map params = new HashMap<>(); + params.put("mode", "com.cloudbees.hudson.plugins.folder.Folder"); + params.put("name", jobName); + params.put("from", ""); + params.put("Submit", "OK"); client.post_form(UrlUtils.toBaseUrl(folder) + "createItem?", params, crumbFlag); } @@ -535,13 +541,9 @@ public LabelWithDetails getLabel(String labelName) throws IOException { */ public Map getComputers() throws IOException { List computers = client.get("computer/", Computer.class).getComputers(); - return Maps.uniqueIndex(computers, new Function() { - @Override - public String apply(Computer computer) { - computer.setClient(client); - return computer.getDisplayName().toLowerCase(); - } - }); + return computers.stream() + .map(SET_CLIENT(this.client)) + .collect(Collectors.toMap(s -> s.getDisplayName().toLowerCase(), Function.identity())); } /** 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 index 308a6d0e..4eadc5c9 100755 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/JenkinsHttpClient.java @@ -6,8 +6,6 @@ package com.offbytwo.jenkins.client; 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.validator.HttpResponseValidator; @@ -47,6 +45,8 @@ 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; @@ -291,7 +291,7 @@ public void post_form(String path, Map data, boolean crumbFlag) if (data != null) { // https://gist.github.com/stuart-warren/7786892 was slightly // helpful here - List queryParams = Lists.newArrayList(); + List queryParams = new ArrayList<>(); for (String param : data.keySet()) { queryParams.add(param + "=" + EncodingUtils.formParameter(data.get(param))); } @@ -493,7 +493,7 @@ protected void setLocalContext(final HttpContext localContext) { private T objectFromResponse(Class cls, HttpResponse response) throws IOException { InputStream content = response.getEntity().getContent(); - byte[] bytes = ByteStreams.toByteArray(content); + byte[] bytes = IOUtils.toByteArray(content); T result = mapper.readValue(bytes, cls); // TODO: original: // T result = mapper.readValue(content, cls); diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/EncodingUtils.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/EncodingUtils.java index 11bd3ff3..4638634b 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/EncodingUtils.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/client/util/EncodingUtils.java @@ -1,7 +1,21 @@ +/* + * Copyright (c) 2019 Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ package com.offbytwo.jenkins.client.util; -import com.google.common.net.UrlEscapers; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +/** + * This class is a help class to centralize the + * encoding parts which will call an appropriate library function. + * + * @author Karl Heinz Marbaise + */ public final class EncodingUtils { private EncodingUtils() { @@ -9,12 +23,24 @@ private EncodingUtils() { public static String encode(String pathPart) { // jenkins doesn't like the + for space, use %20 instead - return UrlEscapers.urlPathSegmentEscaper().escape(pathPart); + try { + return URLEncoder.encode(pathPart, StandardCharsets.UTF_8.displayName()); + } catch (UnsupportedEncodingException e) { + // Should never happen, because that would imply that + // the parameter StandardCharsets.UTF_8 is wrong. + throw new IllegalArgumentException(e); + } } public static String formParameter(String pathPart) { // jenkins doesn't like the + for space, use %20 instead - return UrlEscapers.urlFormParameterEscaper().escape(pathPart); + try { + return URLEncoder.encode(pathPart, StandardCharsets.UTF_8.displayName()); + } catch (UnsupportedEncodingException e) { + // Should never happen, because that would imply that + // the parameter StandardCharsets.UTF_8 is wrong. + throw new IllegalArgumentException(e); + } } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/helper/FunctionalHelper.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/helper/FunctionalHelper.java new file mode 100644 index 00000000..d7f507b7 --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/helper/FunctionalHelper.java @@ -0,0 +1,22 @@ +package com.offbytwo.jenkins.helper; + +import com.offbytwo.jenkins.client.JenkinsHttpConnection; +import com.offbytwo.jenkins.model.BaseModel; + +import java.util.function.Function; + +public final class FunctionalHelper { + + private FunctionalHelper() { + // intentionally empty. + } + + public static final Function SET_CLIENT(JenkinsHttpConnection client) { + return s -> { + s.setClient(client); + return s; + }; + } + + +} 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 20ffbadc..9272c39e 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 @@ -7,9 +7,6 @@ package com.offbytwo.jenkins.model; import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.base.Predicate; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableMap; import com.offbytwo.jenkins.helper.BuildConsoleStreamListener; import org.apache.http.Header; import org.apache.http.HttpResponse; @@ -27,11 +24,17 @@ import java.util.Collection; 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 java.util.stream.Collectors; -import static com.google.common.collect.Collections2.filter; +import java.util.function.Function; +import java.util.stream.Collectors; + +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 @@ -111,7 +114,7 @@ public BuildResult getResult() { }; - private List actions; // TODO: Should be improved. + private List>>> actions; // TODO: Should be improved. private boolean building; private String description; private String displayName; @@ -163,31 +166,12 @@ public boolean isBuilding() { } public List getCauses() { - // actions is a List List[BuildCause] - Collection causes = filter(actions, new Predicate>() { - @Override - public boolean apply(Map action) { - return action.containsKey("causes"); - } - }); - - List result = new ArrayList(); - - if (causes != null && !causes.isEmpty()) { - // The underlying key-value can be either a or a - // . - List> causes_blob = ((Map>>) causes.toArray()[0]) - .get("causes"); - for (Map cause : causes_blob) { - - BuildCause convertToBuildCause = convertToBuildCause(cause); - - result.add(convertToBuildCause); - } - } - - return result; + return actions.stream() + .filter(item -> item.containsKey("causes")) + .flatMap(item -> item.entrySet().stream()) + .flatMap(sub -> sub.getValue().stream()) + .map(item -> convertToBuildCause(item)) + .collect(toList()); } /** @@ -203,9 +187,13 @@ public void updateDisplayNameAndDescription(String displayName, String descripti throws IOException { Objects.requireNonNull(displayName, "displayName is not allowed to be null."); Objects.requireNonNull(description, "description is not allowed to be null."); + //TODO:JDK9+ Map.of()... + Map params = new HashMap<>(); + params.put("displayName", displayName); + params.put("description", description); // TODO: Check what the "core:apply" means? - ImmutableMap params = ImmutableMap.of("displayName", displayName, "description", description, - "core:apply", "", "Submit", "Save"); + params.put("core:apply", ""); + params.put("Submit", "Save"); client.post_form(this.getUrl() + "/configSubmit?", params, crumbFlag); } @@ -231,9 +219,12 @@ public void updateDisplayNameAndDescription(String displayName, String descripti public void updateDisplayName(String displayName, boolean crumbFlag) throws IOException { Objects.requireNonNull(displayName, "displayName is not allowed to be null."); String description = getDescription() == null ? "" : getDescription(); + Map params = new HashMap<>(); + params.put("displayName", displayName); + params.put("description", description); // TODO: Check what the "core:apply" means? - ImmutableMap params = ImmutableMap.of("displayName", displayName, "description", description, - "core:apply", "", "Submit", "Save"); + params.put("core:apply", ""); + params.put("Submit", "Save"); client.post_form(this.getUrl() + "/configSubmit?", params, crumbFlag); } @@ -257,9 +248,13 @@ public void updateDisplayName(String displayName) throws IOException { public void updateDescription(String description, boolean crumbFlag) throws IOException { Objects.requireNonNull(description, "description is not allowed to be null."); String displayName = getDisplayName() == null ? "" : getDisplayName(); + //JDK9+: Map.of(..) + Map params = new HashMap<>(); + params.put("displayName", displayName); + params.put("description", description); // TODO: Check what the "core:apply" means? - ImmutableMap params = ImmutableMap.of("displayName", displayName, "description", description, - "core:apply", "", "Submit", "Save"); + params.put("core:apply", ""); + params.put("Submit", "Save"); client.post_form(this.getUrl() + "/configSubmit?", params, crumbFlag); } @@ -353,33 +348,21 @@ public List getActions() { return actions; } - public Map getParameters() { - Collection parameters = filter(actions, new Predicate>() { - @Override - public boolean apply(Map action) { - return action.containsKey("parameters"); - } - }); - - Map params = new HashMap(); - - if (parameters != null && !parameters.isEmpty()) { - for (Map param : ((Map>>) parameters.toArray()[0]) - .get("parameters")) { - String key = (String) param.get("name"); - Object value = param.get("value"); - params.put(key, String.valueOf(value)); - } - } + public Map getParameters() { + Map parameters = actions.stream() + .filter(item -> item.containsKey("parameters")) + .flatMap(item -> item.entrySet().stream()) + .flatMap(sub -> sub.getValue().stream()) + .collect(toMap(k -> (String) k.get("name"), v -> v.get("value"))); - return params; + return parameters; } /** * @return The full console output of the build. The line separation is done by * {@code CR+LF}. * - * @see streamConsoleOutput method for obtaining logs for running build + * @see {@link #streamConsoleOutput(BuildConsoleStreamListener, int, int, boolean)} method for obtaining logs for running build * * @throws IOException in case of a failure. */ @@ -390,7 +373,7 @@ public String getConsoleOutputText() throws IOException { /** * The full console output with HTML. * - * @see streamConsoleOutput method for obtaining logs for running build + * @see {@link #streamConsoleOutput(BuildConsoleStreamListener, int, int, boolean)} method for obtaining logs for running build * * @return The console output as HTML. * @throws IOException in case of an error. diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerSet.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerSet.java index 7bebc43f..ef2e2047 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerSet.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerSet.java @@ -7,9 +7,7 @@ package com.offbytwo.jenkins.model; import java.util.List; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; +import java.util.stream.Collectors; public class ComputerSet extends BaseModel { private int busyExecutors; @@ -47,13 +45,10 @@ public void setTotalExecutors(int totalExecutors) { } public List getComputers() { - return Lists.transform( computer, new Function() { - @Override - public ComputerWithDetails apply(ComputerWithDetails computerWithDetails) { - computerWithDetails.setClient(client); - return computerWithDetails; - } - }); + return computer.stream().map(s -> { + s.setClient(this.client); + return s; + }).collect(Collectors.toList()); } public void setComputer(List computers) { diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java index 93206009..46958e6f 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java @@ -10,9 +10,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - -import com.google.common.base.Function; import com.offbytwo.jenkins.client.util.EncodingUtils; +import java.util.function.Function; public class ComputerWithDetails extends Computer { @@ -88,8 +87,6 @@ public void toggleOffline(boolean crumbFlag) throws IOException { name = EncodingUtils.encode(displayName); } - Map data = new HashMap(); - data.put( "json", "init" ); client.post( "/computer/" + name + "/toggleOffline", crumbFlag); } @@ -249,11 +246,4 @@ public int hashCode() { return result; } - private class ComputerWithClient implements Function { - @Override - public Computer apply(Computer computer) { - computer.setClient(client); - return computer; - } - } } \ No newline at end of file diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/FolderJob.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/FolderJob.java index 25a26770..a2ce89dc 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/FolderJob.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/FolderJob.java @@ -1,13 +1,15 @@ package com.offbytwo.jenkins.model; +import com.offbytwo.jenkins.helper.FunctionalHelper; + import java.io.IOException; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import com.offbytwo.jenkins.client.util.EncodingUtils; +import static com.offbytwo.jenkins.helper.FunctionalHelper.SET_CLIENT; public class FolderJob extends Job { @@ -46,16 +48,13 @@ public boolean isFolder() { /** * Get a list of all the defined jobs in this folder * - * @return list of defined jobs (summary level, for details @see Job#details + * @return list of defined jobs (summary level, for details {@link Job#details()}. */ public Map getJobs() { - return Maps.uniqueIndex(jobs, new Function() { - @Override - public String apply(Job job) { - job.setClient(client); - return job.getName(); - } - }); + //FIXME: Check for null of jobs? Can that happen? + return jobs.stream() + .map(SET_CLIENT(this.client)) + .collect(Collectors.toMap(k -> k.getName(), Function.identity())); } /** @@ -63,15 +62,15 @@ public String apply(Job job) { * * @param name the name of the job. * @return the given job + * @throws IllegalArgumentException in case if the {@code name} does not exist. */ public Job getJob(String name) { - return Maps.uniqueIndex(jobs, new Function() { - @Override - public String apply(Job job) { - job.setClient(client); - return job.getName(); - } - }).get(name); + //FIXME: Check for null of jobs? Can that happen? + return jobs.stream() + .map(SET_CLIENT(this.client)) + .filter(item -> item.getName().equals(name)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("Job with name " + name + " does not exist.")); } /** @@ -94,8 +93,12 @@ public void createFolder(String folderName) throws IOException { public void createFolder(String folderName, Boolean crumbFlag) throws IOException { // https://gist.github.com/stuart-warren/7786892 was slightly helpful // here - ImmutableMap params = ImmutableMap.of("mode", "com.cloudbees.hudson.plugins.folder.Folder", - "name", EncodingUtils.formParameter(folderName), "from", "", "Submit", "OK"); + //TODO: JDK9+: Map.of(...) + Map params = new HashMap<>(); + params.put("mode", "com.cloudbees.hudson.plugins.folder.Folder"); + params.put("name", folderName); + params.put("from", ""); + params.put("Submit", "OK"); client.post_form(this.getUrl() + "/createItem?", params, crumbFlag); } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Job.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Job.java index 24247c8f..ba1968a1 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Job.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Job.java @@ -15,9 +15,9 @@ import java.net.URI; import java.util.Map; -import com.google.common.base.Function; -import com.google.common.collect.Collections2; import com.offbytwo.jenkins.client.util.EncodingUtils; +import java.util.function.Function; +import java.util.stream.Collectors; public class Job extends BaseModel { @@ -146,7 +146,10 @@ public QueueReference build(Map params, Map filePa * @throws IOException in case of an error. */ public QueueReference build(Map params, Map fileParams, boolean crumbFlag) throws IOException { - String qs = join(Collections2.transform(params.entrySet(), new MapEntryToQueryStringPair()), "&"); + String qs = params.entrySet().stream() + .map(s -> s.getKey() + "=" + s.getValue()) + .collect(Collectors.joining("&")); +// String qs = join(Collections2.transform(params.entrySet(), new MapEntryToQueryStringPair()), "&"); ExtractHeader location = client.post(url + "buildWithParameters?" + qs,null, ExtractHeader.class, fileParams, crumbFlag); return new QueueReference(location.getLocation()); } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java index d203aad5..71bc664a 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java @@ -6,23 +6,22 @@ package com.offbytwo.jenkins.model; -import static com.google.common.collect.Lists.transform; +import com.offbytwo.jenkins.client.util.EncodingUtils; +import com.offbytwo.jenkins.helper.Range; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpResponseException; import java.io.IOException; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; -import org.apache.http.HttpStatus; -import org.apache.http.client.HttpResponseException; - -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.offbytwo.jenkins.client.util.EncodingUtils; -import com.offbytwo.jenkins.helper.Range; +import static com.offbytwo.jenkins.helper.FunctionalHelper.SET_CLIENT; +import static java.util.stream.Collectors.toList; public class JobWithDetails extends Job { @@ -95,12 +94,9 @@ public List getBuilds() { if (builds == null) { return Collections.emptyList(); } else { - return transform(builds, new Function() { - @Override - public Build apply(Build from) { - return buildWithClient(from); - } - }); + return builds.stream() + .map(s -> buildWithClient(s)) + .collect(toList()); } } @@ -129,12 +125,9 @@ public List getAllBuilds() throws IOException { if (builds == null) { return Collections.emptyList(); } else { - return transform(builds, new Function() { - @Override - public Build apply(Build from) { - return buildWithClient(from); - } - }); + return builds.stream() + .map(s -> buildWithClient(s)) + .collect(toList()); } } catch (HttpResponseException e) { // TODO: Thinks about a better handling if the job does not exist? @@ -178,12 +171,9 @@ public List getAllBuilds(Range range) throws IOException { if (builds == null) { return Collections.emptyList(); } else { - return transform(builds, new Function() { - @Override - public Build apply(Build from) { - return buildWithClient(from); - } - }); + return builds.stream() + .map(s -> buildWithClient(s)) + .collect(toList()); } } catch (HttpResponseException e) { // TODO: Thinks about a better handline if the job does not exist? @@ -428,7 +418,9 @@ public List getDownstreamProjects() { if (downstreamProjects == null) { return Collections.emptyList(); } else { - return transform(downstreamProjects, new JobWithClient()); + return downstreamProjects.stream() + .map(SET_CLIENT(this.client)) + .collect(toList()); } } @@ -440,10 +432,16 @@ public List getUpstreamProjects() { if (upstreamProjects == null) { return Collections.emptyList(); } else { - return transform(upstreamProjects, new JobWithClient()); + return upstreamProjects.stream() + .map(SET_CLIENT(this.client)) + .collect(toList()); } } + private static Predicate isBuildNumberEqualTo(int buildNumber) { + return build -> build.getNumber() == buildNumber; + } + public QueueItem getQueueItem() { return this.queueItem; } @@ -452,30 +450,11 @@ public QueueItem getQueueItem() { * Get a build by the given buildNumber. * * @param buildNumber The number to select the build by. - * @return The {@link Build} selected by the given buildnumber - * + * @return The an Optional with the {@link Build} selected by the given buildnumber + * */ - public Build getBuildByNumber(final int buildNumber) { - - Predicate isMatchingBuildNumber = new Predicate() { - - @Override - public boolean apply(Build input) { - return input.getNumber() == buildNumber; - } - }; - - Optional optionalBuild = Iterables.tryFind(builds, isMatchingBuildNumber); - // TODO: Check if we could use Build#NO...instead of Null? - return optionalBuild.orNull() == null ? null : buildWithClient(optionalBuild.orNull()); - } - - private class JobWithClient implements Function { - @Override - public Job apply(Job job) { - job.setClient(client); - return job; - } + public Optional getBuildByNumber(final int buildNumber) { + return builds.stream().filter(isBuildNumberEqualTo(buildNumber)).findFirst(); } /** @@ -507,7 +486,10 @@ public void updateDescription(String description) throws IOException { */ public void updateDescription(String description, boolean crumbFlag) throws IOException { Objects.requireNonNull(description, "description is not allowed to be null."); - ImmutableMap params = ImmutableMap.of("description", description); + //JDK9+ + // Map.of(...); + Map params = new HashMap<>(); + params.put("description", description); client.post_form(this.getUrl() + "/submitDescription?", params, crumbFlag); } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MainView.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MainView.java index b239558d..bef07f0b 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MainView.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MainView.java @@ -6,11 +6,10 @@ package com.offbytwo.jenkins.model; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import com.google.common.collect.Lists; - public class MainView extends BaseModel { private List jobs; @@ -18,7 +17,7 @@ public class MainView extends BaseModel { /* default constructor needed for Jackson */ public MainView() { - this(Lists.newArrayList(), Lists.newArrayList()); + this(new ArrayList<>(), new ArrayList<>()); } public MainView(List jobs, List views) { @@ -27,7 +26,7 @@ public MainView(List jobs, List views) { } public MainView(Job... jobs) { - this(Arrays.asList(jobs), Lists.newArrayList()); + this(Arrays.asList(jobs), new ArrayList<>()); } public List getJobs() { diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenJobWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenJobWithDetails.java index ae2c7c06..bb3f0c62 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenJobWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenJobWithDetails.java @@ -1,21 +1,19 @@ package com.offbytwo.jenkins.model; -import static com.google.common.collect.Lists.transform; +import com.offbytwo.jenkins.client.util.EncodingUtils; +import com.offbytwo.jenkins.helper.FunctionalHelper; +import com.offbytwo.jenkins.helper.Range; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpResponseException; import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; -import org.apache.http.HttpStatus; -import org.apache.http.client.HttpResponseException; - -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.offbytwo.jenkins.client.util.EncodingUtils; -import com.offbytwo.jenkins.helper.Range; +import static com.offbytwo.jenkins.helper.FunctionalHelper.SET_CLIENT; +import static java.util.stream.Collectors.toList; public class MavenJobWithDetails extends MavenJob { @@ -60,12 +58,9 @@ public List getBuilds() { if (builds == null) { return Collections.emptyList(); } else { - return Lists.transform(builds, new Function() { - @Override - public MavenBuild apply(MavenBuild from) { - return buildWithClient(from); - } - }); + return builds.stream() + .map(SET_CLIENT(this.client)) + .collect(toList()); } } @@ -95,12 +90,9 @@ public List getAllBuilds() throws IOException { if (builds == null) { return Collections.emptyList(); } else { - return transform(builds, new Function() { - @Override - public MavenBuild apply(MavenBuild from) { - return buildWithClient(from); - } - }); + return builds.stream() + .map(SET_CLIENT(this.client)) + .collect(toList()); } } catch (HttpResponseException e) { // TODO: Thinks about a better handling if the job does not exist? @@ -146,12 +138,9 @@ public List getAllBuilds(Range range) throws IOException { if (builds == null) { return Collections.emptyList(); } else { - return transform(builds, new Function() { - @Override - public MavenBuild apply(MavenBuild from) { - return buildWithClient(from); - } - }); + return builds.stream() + .map(SET_CLIENT(this.client)) + .collect(toList()); } } catch (HttpResponseException e) { // TODO: Thinks about a better handline if the job does not exist? @@ -271,7 +260,9 @@ public List getDownstreamProjects() { if (downstreamProjects == null) { return Collections.emptyList(); } else { - return Lists.transform(downstreamProjects, new MavenJobWithClient()); + return downstreamProjects.stream() + .map(SET_CLIENT(this.client)) + .collect(toList()); } } @@ -279,23 +270,24 @@ public List getUpstreamProjects() { if (upstreamProjects == null) { return Collections.emptyList(); } else { - return Lists.transform(upstreamProjects, new MavenJobWithClient()); + return upstreamProjects.stream() + .map(SET_CLIENT(this.client)) + .collect(toList()); } } - public MavenBuild getBuildByNumber(final int buildNumber) { - - Predicate isMatchingBuildNumber = new Predicate() { - - @Override - public boolean apply(MavenBuild input) { - return input.getNumber() == buildNumber; - } - }; + private static Predicate isBuildNumberEqualTo(int buildNumber) { + return build -> build.getNumber() == buildNumber; + } - Optional optionalBuild = Iterables.tryFind(builds, isMatchingBuildNumber); - // TODO: Check if we could use Build#NO...instead of Null? - return optionalBuild.orNull() == null ? null : buildWithClient(optionalBuild.orNull()); + /** + * @param buildNumber The build you would like to select. + * @return Optional which contains the {@link MavenBuild}. + */ + public Optional getBuildByNumber(final int buildNumber) { + return builds.stream() + .filter(isBuildNumberEqualTo(buildNumber)) + .findFirst(); } private MavenBuild buildWithClient(MavenBuild from) { @@ -304,11 +296,4 @@ private MavenBuild buildWithClient(MavenBuild from) { return ret; } - private class MavenJobWithClient implements Function { - @Override - public Job apply(Job job) { - job.setClient(client); - return job; - } - } } diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/FirstTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/FirstTest.java new file mode 100644 index 00000000..7d512198 --- /dev/null +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/FirstTest.java @@ -0,0 +1,56 @@ +package com.offbytwo.jenkins; + +import com.offbytwo.jenkins.client.util.EncodingUtils; +import com.offbytwo.jenkins.model.Build; +import org.apache.http.client.utils.URIBuilder; +import org.junit.Test; + +import java.net.URI; +import java.util.List; + +public class FirstTest { + + @Test + public void name() { + String url = "http://localhost:8080/job/test/1"; + + URI uri = URI.create(url); + System.out.println("Fragement:" + uri.getFragment()); + System.out.println("Host:" + uri.getHost()); + System.out.println("Authority:" + uri.getAuthority()); + System.out.println("Path:" + uri.getPath()); + System.out.println("Query:" + uri.getQuery()); + System.out.println("Port:" + uri.getPort()); + System.out.println("Scheme:" + uri.getScheme()); + + + URIBuilder uriBuilder = new URIBuilder(uri); + uriBuilder.setPath(uri.getPath() + "/testReport"); + uriBuilder.addParameter("depth", "1"); + + System.out.println("Resulting: " + uriBuilder.toString()); + + } + + @Test + public void secondTest() { + + + String url = "http://localhost:8080/"; + + +// List builds = client.get(path + "job/" + EncodingUtils.encode(this.getName()) +// + "?tree=allBuilds[number[*],url[*],queueId[*]]", AllBuilds.class).getAllBuilds(); + + // url + "/testReport/?depth=1" + +// this.getUrl() + "/testReport/?depth=1", TestReport.class + +// uri.getRawPath(); +// +// public URI(String scheme, +// String userInfo, String host, int port, +// String path, String query, String fragment) + + } +} diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java index 9e9d50aa..0c553ce1 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/JenkinsServerTest.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import org.apache.http.entity.ContentType; @@ -25,7 +26,6 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; -import com.google.common.base.Optional; import com.offbytwo.jenkins.client.JenkinsHttpClient; import com.offbytwo.jenkins.client.JenkinsHttpConnection; import com.offbytwo.jenkins.model.FolderJob; diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/EncodingUtilsTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/EncodingUtilsTest.java index 973eb0a8..358ac7f5 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/EncodingUtilsTest.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/client/util/EncodingUtilsTest.java @@ -1,21 +1,31 @@ +/* + * Copyright (c) 2019 Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ package com.offbytwo.jenkins.client.util; import org.junit.Test; import static org.assertj.core.api.Assertions.assertThat; +/** + * This class is a unit test for the helper class {@link EncodingUtils}. + * + * @author Karl Heinz Marbaise + */ public class EncodingUtilsTest { @Test public void encodeShouldReturnEncodedDoubleQuoteAndSpace() { String result = EncodingUtils.encode("!\"& "); - assertThat(result).isEqualTo("!%22&%20"); + assertThat(result).isEqualTo("%21%22%26+"); } @Test public void encodeShouldReturnNotEncodeSafeChars() { String result = EncodingUtils.encode("-._~!$'()*,;&=@:+"); - assertThat(result).isEqualTo("-._~!$'()*,;&=@:+"); + assertThat(result).isEqualTo("-._%7E%21%24%27%28%29*%2C%3B%26%3D%40%3A%2B"); } @Test public void encodeShouldReturnNotEncodeAlpha() { diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/FolderTestsIT.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/FolderTestsIT.java index c6549413..098102c0 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/FolderTestsIT.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/FolderTestsIT.java @@ -5,6 +5,7 @@ import hudson.model.UpdateCenter; import java.util.List; +import java.util.Optional; import java.util.Vector; import jenkins.model.Jenkins; @@ -19,7 +20,6 @@ import org.kohsuke.stapler.StaplerResponse; import org.mockito.Mockito; -import com.google.common.base.Optional; import com.offbytwo.jenkins.JenkinsServer; import com.offbytwo.jenkins.model.FolderJob; import com.offbytwo.jenkins.model.JobWithDetails; @@ -67,7 +67,7 @@ public void testFolderPluginAPIs() throws Exception { JobWithDetails root = server.getJob("root"); Assert.assertNotNull(root); - Optional rootFolder = server.getFolderJob(root); + java.util.Optional rootFolder = server.getFolderJob(root); Assert.assertTrue(rootFolder.isPresent()); server.createFolder(rootFolder.get(), "subfolder"); diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/JenkinsServerIT.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/JenkinsServerIT.java index d7f19a10..b32d027b 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/JenkinsServerIT.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/integration/JenkinsServerIT.java @@ -88,7 +88,7 @@ public void shouldSupportBooleanParameters() throws Exception { JobWithDetails job = server.getJobs().get(JENKINS_TEST_JOB).details(); BuildWithDetails build = job.getBuilds().get(0).details(); - assertEquals("true", build.getParameters().get("someValue")); + assertEquals(Boolean.TRUE, build.getParameters().get("someValue")); } @Test diff --git a/pom.xml b/pom.xml index 481dedff..4a04fdf7 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ com.offbytwo.jenkins jenkins-client-parent - 0.3.9-SNAPSHOT + 0.4.0-SNAPSHOT pom @@ -58,7 +58,6 @@ 1.4.7-jenkins-1 1.6.1 3.8.1 - 17.0 2.4 4.5.8 4.4.11 @@ -126,12 +125,6 @@ - - com.google.guava - guava - ${guava.version} - - org.apache.commons commons-lang3 From a5a59ca43a1c1ca3f45ad2a7a0178b6f58344346 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sun, 7 Apr 2019 19:23:42 +0200 Subject: [PATCH 48/68] Fixed JavaDoc issues. Generate JavaDoc during site generation. --- .../com/offbytwo/jenkins/JenkinsServer.java | 2 - .../jenkins/model/BuildWithDetails.java | 10 +--- .../java/com/offbytwo/jenkins/FirstTest.java | 56 ------------------- pom.xml | 46 ++++----------- 4 files changed, 14 insertions(+), 100 deletions(-) delete mode 100644 jenkins-client/src/test/java/com/offbytwo/jenkins/FirstTest.java diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java index f76da927..ee1672a4 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java @@ -14,8 +14,6 @@ import javax.xml.bind.JAXBException; -import com.offbytwo.jenkins.helper.FunctionalHelper; -import com.offbytwo.jenkins.model.BaseModel; import org.apache.http.HttpStatus; import org.apache.http.client.HttpResponseException; import org.apache.http.entity.ContentType; 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 9272c39e..b129b732 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 @@ -21,17 +21,12 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.Collection; 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 java.util.stream.Collectors; - -import java.util.function.Function; -import java.util.stream.Collectors; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; @@ -362,7 +357,7 @@ public Map getParameters() { * @return The full console output of the build. The line separation is done by * {@code CR+LF}. * - * @see {@link #streamConsoleOutput(BuildConsoleStreamListener, int, int, boolean)} method for obtaining logs for running build + * @see #streamConsoleOutput(BuildConsoleStreamListener, int, int, boolean) method for obtaining logs for running build * * @throws IOException in case of a failure. */ @@ -373,7 +368,7 @@ public String getConsoleOutputText() throws IOException { /** * The full console output with HTML. * - * @see {@link #streamConsoleOutput(BuildConsoleStreamListener, int, int, boolean)} method for obtaining logs for running build + * @see #streamConsoleOutput(BuildConsoleStreamListener, int, int, boolean) method for obtaining logs for running build * * @return The console output as HTML. * @throws IOException in case of an error. @@ -430,6 +425,7 @@ public void streamConsoleOutput(final BuildConsoleStreamListener listener, final * Use this method to periodically obtain logs from jenkins and skip chunks that were already received * * @param bufferOffset offset in console lo + * @param crumbFlag true or false. * @return ConsoleLog object containing console output of the build. The line separation is done by * {@code CR+LF}. * @throws IOException in case of a failure. diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/FirstTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/FirstTest.java deleted file mode 100644 index 7d512198..00000000 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/FirstTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.offbytwo.jenkins; - -import com.offbytwo.jenkins.client.util.EncodingUtils; -import com.offbytwo.jenkins.model.Build; -import org.apache.http.client.utils.URIBuilder; -import org.junit.Test; - -import java.net.URI; -import java.util.List; - -public class FirstTest { - - @Test - public void name() { - String url = "http://localhost:8080/job/test/1"; - - URI uri = URI.create(url); - System.out.println("Fragement:" + uri.getFragment()); - System.out.println("Host:" + uri.getHost()); - System.out.println("Authority:" + uri.getAuthority()); - System.out.println("Path:" + uri.getPath()); - System.out.println("Query:" + uri.getQuery()); - System.out.println("Port:" + uri.getPort()); - System.out.println("Scheme:" + uri.getScheme()); - - - URIBuilder uriBuilder = new URIBuilder(uri); - uriBuilder.setPath(uri.getPath() + "/testReport"); - uriBuilder.addParameter("depth", "1"); - - System.out.println("Resulting: " + uriBuilder.toString()); - - } - - @Test - public void secondTest() { - - - String url = "http://localhost:8080/"; - - -// List builds = client.get(path + "job/" + EncodingUtils.encode(this.getName()) -// + "?tree=allBuilds[number[*],url[*],queueId[*]]", AllBuilds.class).getAllBuilds(); - - // url + "/testReport/?depth=1" - -// this.getUrl() + "/testReport/?depth=1", TestReport.class - -// uri.getRawPath(); -// -// public URI(String scheme, -// String userInfo, String host, int port, -// String path, String query, String fragment) - - } -} diff --git a/pom.xml b/pom.xml index 4a04fdf7..8015cefa 100644 --- a/pom.xml +++ b/pom.xml @@ -406,43 +406,18 @@ org.apache.maven.plugins maven-project-info-reports-plugin - - - org.apache.maven.plugins - maven-javadoc-plugin - - - - javadoc-no-fork - aggregate-no-fork - - - - @@ -490,7 +465,8 @@ attach-javadocs - jar + javadoc-no-fork + test-javadoc-no-fork From 0f1a8bc26f7aad97e83eb5217d239e0d4b8d855f Mon Sep 17 00:00:00 2001 From: mivola Date: Mon, 15 Apr 2019 20:19:42 +0200 Subject: [PATCH 49/68] fixes #360 by changing the return value from void to the appropriate object (#403) --- .../com/offbytwo/jenkins/JenkinsServer.java | 139 ++++++++++-------- .../com/offbytwo/jenkins/model/Artifact.java | 9 +- .../com/offbytwo/jenkins/model/BaseModel.java | 3 +- .../com/offbytwo/jenkins/model/Build.java | 9 +- .../offbytwo/jenkins/model/BuildCause.java | 18 ++- .../jenkins/model/BuildChangeSet.java | 6 +- .../jenkins/model/BuildChangeSetAuthor.java | 6 +- .../jenkins/model/BuildChangeSetItem.java | 27 ++-- .../jenkins/model/BuildChangeSetPath.java | 6 +- .../jenkins/model/BuildWithDetails.java | 33 +++-- .../offbytwo/jenkins/model/CauseAction.java | 9 +- .../com/offbytwo/jenkins/model/Computer.java | 26 ++-- .../offbytwo/jenkins/model/ComputerSet.java | 12 +- .../jenkins/model/ComputerWithDetails.java | 22 +-- .../offbytwo/jenkins/model/ConsoleLog.java | 9 +- .../offbytwo/jenkins/model/Executable.java | 6 +- .../com/offbytwo/jenkins/model/Executor.java | 18 ++- .../offbytwo/jenkins/model/ExtractHeader.java | 3 +- .../com/offbytwo/jenkins/model/FolderJob.java | 8 +- .../offbytwo/jenkins/model/HourMinSec10.java | 9 +- .../jenkins/model/JacocoCoverageReport.java | 24 ++- .../jenkins/model/JacocoCoverageResult.java | 26 +++- .../jenkins/model/JobConfiguration.java | 3 +- .../jenkins/model/JobWithDetails.java | 15 +- .../jenkins/model/LoadStatistics.java | 9 +- .../com/offbytwo/jenkins/model/MainView.java | 6 +- .../offbytwo/jenkins/model/MavenArtifact.java | 24 ++- .../jenkins/model/MavenModuleRecord.java | 15 +- .../offbytwo/jenkins/model/OfflineCause.java | 18 ++- .../jenkins/model/ParameterDefinitions.java | 6 +- .../model/ParametersDefinitionProperty.java | 3 +- .../com/offbytwo/jenkins/model/Plugin.java | 41 ++++-- .../jenkins/model/PluginDependency.java | 57 ++++--- .../offbytwo/jenkins/model/PluginManager.java | 3 +- .../com/offbytwo/jenkins/model/Queue.java | 9 +- .../com/offbytwo/jenkins/model/QueueItem.java | 36 +++-- .../jenkins/model/QueueItemActions.java | 3 +- .../com/offbytwo/jenkins/model/Statis.java | 6 +- .../model/StringParameterDefinition.java | 9 +- .../com/offbytwo/jenkins/model/TestCase.java | 27 ++-- .../com/offbytwo/jenkins/model/TestChild.java | 6 +- .../jenkins/model/TestChildReport.java | 20 +-- .../offbytwo/jenkins/model/TestReport.java | 15 +- .../offbytwo/jenkins/model/TestResult.java | 32 ++-- .../offbytwo/jenkins/model/TestSuites.java | 15 +- .../java/com/offbytwo/jenkins/model/View.java | 9 +- 46 files changed, 506 insertions(+), 309 deletions(-) diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java index ee1672a4..e9973d59 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java @@ -341,8 +341,8 @@ public Optional getFolderJob(Job job) throws IOException { * the job. * @throws IOException in case of an error. */ - public void createJob(String jobName, String jobXml) throws IOException { - createJob(null, jobName, jobXml, false); + public JenkinsServer createJob(String jobName, String jobXml) throws IOException { + return createJob(null, jobName, jobXml, false); } /** @@ -355,8 +355,8 @@ public void createJob(String jobName, String jobXml) throws IOException { * 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); } /** @@ -369,8 +369,8 @@ public void createJob(String jobName, String jobXml, Boolean crumbFlag) throws I * the job. * @throws IOException in case of an error. */ - public void createJob(FolderJob folder, String jobName, String jobXml) throws IOException { - createJob(folder, jobName, jobXml, false); + public JenkinsServer createJob(FolderJob folder, String jobName, String jobXml) throws IOException { + return createJob(folder, jobName, jobXml, false); } /** @@ -385,8 +385,10 @@ public void createJob(FolderJob folder, String jobName, String jobXml) throws IO * false otherwise. * @throws IOException in case of an error. */ - public void createJob(FolderJob folder, String jobName, String jobXml, Boolean crumbFlag) throws IOException { + 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; } /** @@ -396,8 +398,8 @@ public void createJob(FolderJob folder, String jobName, String jobXml, Boolean c * @param viewXml The configuration for the view. * @throws IOException in case of an error. */ - public void createView(String viewName, String viewXml) throws IOException { - createView(null, viewName, viewXml, false); + public JenkinsServer createView(String viewName, String viewXml) throws IOException { + return createView(null, viewName, viewXml, false); } /** @@ -409,8 +411,8 @@ public void createView(String viewName, String viewXml) throws IOException { * false otherwise. * @throws IOException in case of an error. */ - public void createView(String viewName, String viewXml, Boolean crumbFlag) throws IOException { - createView(null, viewName, viewXml, crumbFlag); + public JenkinsServer createView(String viewName, String viewXml, Boolean crumbFlag) throws IOException { + return createView(null, viewName, viewXml, crumbFlag); } /** @@ -422,8 +424,8 @@ public void createView(String viewName, String viewXml, Boolean crumbFlag) throw * @param viewXml The configuration for the view. * @throws IOException in case of an error. */ - public void createView(FolderJob folder, String viewName, String viewXml) throws IOException { - createView(folder, viewName, viewXml, false); + public JenkinsServer createView(FolderJob folder, String viewName, String viewXml) throws IOException { + return createView(folder, viewName, viewXml, false); } /** @@ -437,9 +439,11 @@ public void createView(FolderJob folder, String viewName, String viewXml) throws * false otherwise. * @throws IOException in case of an error. */ - public void createView(FolderJob folder, String viewName, String viewXml, Boolean crumbFlag) throws IOException { + 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; } /** @@ -448,8 +452,8 @@ public void createView(FolderJob folder, String viewName, String viewXml, Boolea * @param folderName name of the folder. * @throws IOException in case of an error. */ - public void createFolder(String folderName) throws IOException { - createFolder(null, folderName, false); + public JenkinsServer createFolder(String folderName) throws IOException { + return createFolder(null, folderName, false); } /** @@ -460,8 +464,8 @@ public void createFolder(String folderName) throws IOException { * false otherwise. * @throws IOException in case of an error. */ - public void createFolder(String folderName, Boolean crumbFlag) throws IOException { - createFolder(null, folderName, crumbFlag); + public JenkinsServer createFolder(String folderName, Boolean crumbFlag) throws IOException { + return createFolder(null, folderName, crumbFlag); } /** @@ -471,8 +475,8 @@ public void createFolder(String folderName, Boolean crumbFlag) throws IOExceptio * @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); } /** @@ -484,7 +488,7 @@ public void createFolder(FolderJob folder, String jobName) throws IOException { * false otherwise. * @throws IOException in case of an error. */ - public void createFolder(FolderJob folder, String jobName, Boolean crumbFlag) throws IOException { + public JenkinsServer createFolder(FolderJob folder, String jobName, Boolean crumbFlag) throws IOException { // https://gist.github.com/stuart-warren/7786892 was slightly helpful // here //TODO: JDK9+: Map.of(...) @@ -494,6 +498,7 @@ public void createFolder(FolderJob folder, String jobName, Boolean crumbFlag) th params.put("from", ""); params.put("Submit", "OK"); client.post_form(UrlUtils.toBaseUrl(folder) + "createItem?", params, crumbFlag); + return this; } /** @@ -573,20 +578,24 @@ public PluginManager getPluginManager() throws IOException { * @param viewXml the view configuration. * @throws IOException in case of an error. */ - public void updateView(String viewName, String viewXml) throws IOException { - this.updateView(viewName, viewXml, true); + public JenkinsServer updateView(String viewName, String viewXml) throws IOException { + return this.updateView(viewName, viewXml, true); } - public void updateView(String viewName, String viewXml, boolean crumbFlag) throws IOException { + public JenkinsServer updateView(String viewName, String viewXml, boolean crumbFlag) throws IOException { client.post_xml("/view/" + EncodingUtils.encode(viewName) + "/config.xml", viewXml, crumbFlag); + return this; } - public void updateView(FolderJob folder, String viewName, String viewXml) throws IOException { + public JenkinsServer updateView(FolderJob folder, String viewName, String viewXml) throws IOException { client.post_xml(UrlUtils.toBaseUrl(folder) + "view/" + EncodingUtils.encode(viewName) + "/config.xml", viewXml, true); + return this; } - public void updateView(FolderJob folder, String viewName, String viewXml, boolean crumbFlag) throws IOException { + public JenkinsServer updateView(FolderJob folder, String viewName, String viewXml, boolean crumbFlag) + throws IOException { client.post_xml(UrlUtils.toBaseUrl(folder) + "view/" + EncodingUtils.encode(viewName) + "/config.xml", viewXml, crumbFlag); + return this; } /** @@ -596,8 +605,8 @@ public void updateView(FolderJob folder, String viewName, String viewXml, boolea * @param jobXml the configuration to be used for updating. * @throws IOException in case of an error. */ - public void updateJob(String jobName, String jobXml) throws IOException { - this.updateJob(jobName, jobXml, true); + public JenkinsServer updateJob(String jobName, String jobXml) throws IOException { + return this.updateJob(jobName, jobXml, true); } /** @@ -608,8 +617,8 @@ public void updateJob(String jobName, String jobXml) throws IOException { * @param crumbFlag true/false. * @throws IOException in case of an error. */ - public void updateJob(String jobName, String jobXml, boolean crumbFlag) throws IOException { - updateJob(null, jobName, jobXml, crumbFlag); + public JenkinsServer updateJob(String jobName, String jobXml, boolean crumbFlag) throws IOException { + return updateJob(null, jobName, jobXml, crumbFlag); } /** @@ -621,8 +630,10 @@ public void updateJob(String jobName, String jobXml, boolean crumbFlag) throws I * @param crumbFlag true/false. * @throws IOException in case of an error. */ - public void updateJob(FolderJob folder, String jobName, String jobXml, boolean crumbFlag) throws IOException { + public JenkinsServer updateJob(FolderJob folder, String jobName, String jobXml, boolean crumbFlag) + throws IOException { client.post_xml(UrlUtils.toJobBaseUrl(folder, jobName) + "/config.xml", jobXml, crumbFlag); + return this; } /** @@ -634,12 +645,12 @@ public void updateJob(FolderJob folder, String jobName, String jobXml, boolean c * @throws JAXBException in case of an error. * @throws DocumentException in case of an error. */ - public void addStringParam(String jobName, String name, String description, String defaultValue) + public JenkinsServer addStringParam(String jobName, String name, String description, String defaultValue) throws IOException, JAXBException, DocumentException { String jobXml = this.getJobXml(jobName); JobConfiguration jobConf = new JobConfiguration(jobXml); jobXml = jobConf.addStringParam(name, description, defaultValue).asXml(); - this.updateJob(jobName, jobXml); + return this.updateJob(jobName, jobXml); } /** @@ -647,13 +658,13 @@ public void addStringParam(String jobName, String name, String description, Stri * * @throws IOException in case of an error. */ - public void quietDown() throws IOException { + public JenkinsServer quietDown() throws IOException { try { client.get("/quietDown/"); } catch (org.apache.http.client.ClientProtocolException e) { LOGGER.error("quietDown()", e); } - + return this; } /** @@ -661,12 +672,13 @@ public void quietDown() throws IOException { * * @throws IOException in case of an error. */ - public void cancelQuietDown() throws IOException { + public JenkinsServer cancelQuietDown() throws IOException { try { client.post("/cancelQuietDown/"); } catch (org.apache.http.client.ClientProtocolException e) { LOGGER.error("cancelQuietDown()", e); } + return this; } /** @@ -677,8 +689,8 @@ public void cancelQuietDown() throws IOException { * * @throws IOException in case of an error. */ - public void deleteJob(FolderJob folder, String jobName) throws IOException { - deleteJob(folder, jobName, false); + public JenkinsServer deleteJob(FolderJob folder, String jobName) throws IOException { + return deleteJob(folder, jobName, false); } /** @@ -689,8 +701,9 @@ public void deleteJob(FolderJob folder, String jobName) throws IOException { * @param crumbFlag The crumbFlag * @throws IOException in case of problems. */ - public void deleteJob(FolderJob folder, String jobName, boolean crumbFlag) throws IOException { + public JenkinsServer deleteJob(FolderJob folder, String jobName, boolean crumbFlag) throws IOException { client.post(UrlUtils.toJobBaseUrl(folder, jobName) + "/doDelete", crumbFlag); + return this; } /** @@ -699,8 +712,8 @@ public void deleteJob(FolderJob folder, String jobName, boolean crumbFlag) throw * @param jobName The name of the job which should be deleted. * @throws IOException in case of an error. */ - public void deleteJob(String jobName) throws IOException { - deleteJob(jobName, false); + public JenkinsServer deleteJob(String jobName) throws IOException { + return deleteJob(jobName, false); } /** @@ -711,8 +724,9 @@ public void deleteJob(String jobName) throws IOException { * false otherwise. * @throws IOException In case of an failure. */ - public void deleteJob(String jobName, boolean crumbFlag) throws IOException { + public JenkinsServer deleteJob(String jobName, boolean crumbFlag) throws IOException { client.post("/job/" + EncodingUtils.encode(jobName) + "/doDelete", crumbFlag); + return this; } /** @@ -721,8 +735,8 @@ public void deleteJob(String jobName, boolean crumbFlag) 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 { - disableJob(jobName, false); + public JenkinsServer disableJob(String jobName) throws IOException { + return disableJob(jobName, false); } /** @@ -733,8 +747,9 @@ public void disableJob(String jobName) throws IOException { * 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; } /** @@ -743,8 +758,8 @@ public void disableJob(String jobName, boolean crumbFlag) 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 { - enableJob( jobName, false ); + public JenkinsServer enableJob(String jobName) throws IOException { + return enableJob(jobName, false); } /** @@ -755,8 +770,9 @@ public void enableJob(String jobName) throws IOException { * 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; } /** @@ -842,8 +858,8 @@ public Build getBuild(QueueItem q) throws IOException { * @param newJobName The new job name. * @throws IOException In case of a failure. */ - public void renameJob(String oldJobName, String newJobName) throws IOException { - renameJob(null, oldJobName, newJobName, false); + public JenkinsServer renameJob(String oldJobName, String newJobName) throws IOException { + return renameJob(null, oldJobName, newJobName, false); } /** @@ -855,8 +871,9 @@ public void renameJob(String oldJobName, String newJobName) throws IOException { * false otherwise. * @throws IOException In case of a failure. */ - public void renameJob(String oldJobName, String newJobName, Boolean crumbFlag) throws IOException { + public JenkinsServer renameJob(String oldJobName, String newJobName, Boolean crumbFlag) throws IOException { renameJob(null, oldJobName, newJobName, crumbFlag); + return this; } /** @@ -867,8 +884,8 @@ public void renameJob(String oldJobName, String newJobName, Boolean crumbFlag) t * @param newJobName The new job name. * @throws IOException In case of a failure. */ - public void renameJob(FolderJob folder, String oldJobName, String newJobName) throws IOException { - renameJob(folder, oldJobName, newJobName, false); + public JenkinsServer renameJob(FolderJob folder, String oldJobName, String newJobName) throws IOException { + return renameJob(folder, oldJobName, newJobName, false); } /** @@ -881,11 +898,12 @@ public void renameJob(FolderJob folder, String oldJobName, String newJobName) th * false otherwise. * @throws IOException In case of a failure. */ - public void renameJob(FolderJob folder, String oldJobName, String newJobName, Boolean crumbFlag) + 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; } @@ -910,12 +928,13 @@ public void close() { * @throws IOException * in case of an error. */ - public void restart(Boolean crumbFlag) throws IOException { + 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; } /** @@ -928,12 +947,13 @@ public void restart(Boolean crumbFlag) throws IOException { * @throws IOException * in case of an error. */ - public void safeRestart(Boolean crumbFlag) throws IOException { + 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; } /** @@ -945,13 +965,13 @@ public void safeRestart(Boolean crumbFlag) throws IOException { * @throws IOException * in case of an error. */ - // - public void exit(Boolean crumbFlag) throws IOException { + 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; } /** @@ -964,11 +984,12 @@ public void exit(Boolean crumbFlag) throws IOException { * @throws IOException * in case of an error. */ - public void safeExit(Boolean crumbFlag) throws IOException { + 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/model/Artifact.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Artifact.java index 6d0b0e69..a6c7a2f0 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Artifact.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Artifact.java @@ -16,24 +16,27 @@ public String getDisplayPath() { return displayPath; } - public void setDisplayPath(String displayPath) { + public Artifact setDisplayPath(String displayPath) { this.displayPath = displayPath; + return this; } public String getFileName() { return fileName; } - public void setFileName(String fileName) { + public Artifact setFileName(String fileName) { this.fileName = fileName; + return this; } public String getRelativePath() { return relativePath; } - public void setRelativePath(String relativePath) { + public Artifact setRelativePath(String relativePath) { this.relativePath = relativePath; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java index 95f70bab..9c850ba2 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java @@ -43,7 +43,8 @@ public JenkinsHttpConnection getClient() { * Set the HTTP client. * @param client {@link JenkinsHttpConnection}. */ - public void setClient(final JenkinsHttpConnection client) { + public BaseModel setClient(final JenkinsHttpConnection client) { this.client = client; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Build.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Build.java index 2d936d1b..470707d9 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Build.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Build.java @@ -83,16 +83,19 @@ public String getUrl() { return url; } - protected void setNumber(int number) { + protected Build setNumber(int number) { this.number = number; + return this; } - protected void setQueueId(int queueId) { + protected Build setQueueId(int queueId) { this.queueId = queueId; + return this; } - protected void setUrl(String url) { + protected Build setUrl(String url) { this.url = url; + return this; } /** diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildCause.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildCause.java index ab15f94f..821a027f 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildCause.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildCause.java @@ -29,48 +29,54 @@ public String getShortDescription() { return shortDescription; } - public void setShortDescription(String shortDescription) { + public BuildCause setShortDescription(String shortDescription) { this.shortDescription = shortDescription; + return this; } public int getUpstreamBuild() { return upstreamBuild; } - public void setUpstreamBuild(Integer upstreamBuild) { + public BuildCause setUpstreamBuild(Integer upstreamBuild) { this.upstreamBuild = upstreamBuild; + return this; } public String getUpstreamProject() { return upstreamProject; } - public void setUpstreamProject(String upstreamProject) { + public BuildCause setUpstreamProject(String upstreamProject) { this.upstreamProject = upstreamProject; + return this; } public String getUpstreamUrl() { return upstreamUrl; } - public void setUpstreamUrl(String upstreamUrl) { + public BuildCause setUpstreamUrl(String upstreamUrl) { this.upstreamUrl = upstreamUrl; + return this; } public String getUserId() { return userId; } - public void setUserId(String userId) { + public BuildCause setUserId(String userId) { this.userId = userId; + return this; } public String getUserName() { return userName; } - public void setUserName(String userName) { + public BuildCause setUserName(String userName) { this.userName = userName; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSet.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSet.java index 1987cc49..2b7cf520 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSet.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSet.java @@ -24,8 +24,9 @@ public class BuildChangeSet { /** * @param items {@link BuildChangeSet} */ - public void setItems(List items) { + public BuildChangeSet setItems(List items) { this.items = items; + return this; } /** @@ -45,8 +46,9 @@ public String getKind() { /** * @param kind the kind of (usually svn, git). */ - public void setKind(String kind) { + public BuildChangeSet setKind(String kind) { this.kind = kind; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetAuthor.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetAuthor.java index 9abdd1ba..af416581 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetAuthor.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetAuthor.java @@ -13,16 +13,18 @@ public String getAbsoluteUrl() { return absoluteUrl; } - public void setAbsoluteUrl(String absoluteUrl) { + public BuildChangeSetAuthor setAbsoluteUrl(String absoluteUrl) { this.absoluteUrl = absoluteUrl; + return this; } public String getFullName() { return fullName; } - public void setFullName(String fullName) { + public BuildChangeSetAuthor setFullName(String fullName) { this.fullName = fullName; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetItem.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetItem.java index e817d12b..922a19b1 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetItem.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetItem.java @@ -27,72 +27,81 @@ public List getAffectedPaths() { return affectedPaths; } - public void setAffectedPaths(List affectedPaths) { + public BuildChangeSetItem setAffectedPaths(List affectedPaths) { this.affectedPaths = affectedPaths; + return this; } public String getCommitId() { return commitId; } - public void setCommitId(String commitId) { + public BuildChangeSetItem setCommitId(String commitId) { this.commitId = commitId; + return this; } public String getTimestamp() { return timestamp; } - public void setTimestamp(String timeStamp) { + public BuildChangeSetItem setTimestamp(String timeStamp) { this.timestamp = timeStamp; + return this; } public String getComment() { return comment; } - public void setComment(String comment) { + public BuildChangeSetItem setComment(String comment) { this.comment = comment; + return this; } public String getDate() { return date; } - public void setDate(String date) { + public BuildChangeSetItem setDate(String date) { this.date = date; + return this; } public String getId() { return id; } - public void setId(String id) { + public BuildChangeSetItem setId(String id) { this.id = id; + return this; } public String getMsg() { return msg; } - public void setMsg(String msg) { + public BuildChangeSetItem setMsg(String msg) { this.msg = msg; + return this; } public List getPaths() { return paths; } - public void setPaths(List paths) { + public BuildChangeSetItem setPaths(List paths) { this.paths = paths; + return this; } public BuildChangeSetAuthor getAuthor() { return author; } - public void setAuthor(BuildChangeSetAuthor author) { + public BuildChangeSetItem setAuthor(BuildChangeSetAuthor author) { this.author = author; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetPath.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetPath.java index e5078f3a..5758ee78 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetPath.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildChangeSetPath.java @@ -27,16 +27,18 @@ public String getEditType() { * @param editType the SCM operation, add or edit or delete * @see EditType */ - public void setEditType(String 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/BuildWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BuildWithDetails.java index b129b732..ab9e201d 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 @@ -178,7 +178,7 @@ public List getCauses() { * @param crumbFlag true or false. * @throws IOException in case of errors. */ - public void updateDisplayNameAndDescription(String displayName, String description, boolean crumbFlag) + public BuildWithDetails updateDisplayNameAndDescription(String displayName, String description, boolean crumbFlag) throws IOException { Objects.requireNonNull(displayName, "displayName is not allowed to be null."); Objects.requireNonNull(description, "description is not allowed to be null."); @@ -190,6 +190,7 @@ public void updateDisplayNameAndDescription(String displayName, String descripti params.put("core:apply", ""); params.put("Submit", "Save"); client.post_form(this.getUrl() + "/configSubmit?", params, crumbFlag); + return this; } /** @@ -200,8 +201,8 @@ public void updateDisplayNameAndDescription(String displayName, String descripti * @param description The description which should be set. * @throws IOException in case of errors. */ - public void updateDisplayNameAndDescription(String displayName, String description) throws IOException { - updateDisplayNameAndDescription(displayName, description, false); + public BuildWithDetails updateDisplayNameAndDescription(String displayName, String description) throws IOException { + return updateDisplayNameAndDescription(displayName, description, false); } /** @@ -211,7 +212,7 @@ public void updateDisplayNameAndDescription(String displayName, String descripti * @param crumbFlag true or false. * @throws IOException in case of errors. */ - public void updateDisplayName(String displayName, boolean crumbFlag) throws IOException { + public BuildWithDetails updateDisplayName(String displayName, boolean crumbFlag) throws IOException { Objects.requireNonNull(displayName, "displayName is not allowed to be null."); String description = getDescription() == null ? "" : getDescription(); Map params = new HashMap<>(); @@ -221,6 +222,7 @@ public void updateDisplayName(String displayName, boolean crumbFlag) throws IOEx params.put("core:apply", ""); params.put("Submit", "Save"); client.post_form(this.getUrl() + "/configSubmit?", params, crumbFlag); + return this; } /** @@ -229,8 +231,8 @@ public void updateDisplayName(String displayName, boolean crumbFlag) throws IOEx * @param displayName The new displayName which should be set. * @throws IOException in case of errors. */ - public void updateDisplayName(String displayName) throws IOException { - updateDisplayName(displayName, false); + public BuildWithDetails updateDisplayName(String displayName) throws IOException { + return updateDisplayName(displayName, false); } /** @@ -240,7 +242,7 @@ public void updateDisplayName(String displayName) throws IOException { * @param crumbFlag true or false. * @throws IOException in case of errors. */ - public void updateDescription(String description, boolean crumbFlag) throws IOException { + public BuildWithDetails updateDescription(String description, boolean crumbFlag) throws IOException { Objects.requireNonNull(description, "description is not allowed to be null."); String displayName = getDisplayName() == null ? "" : getDisplayName(); //JDK9+: Map.of(..) @@ -251,6 +253,7 @@ public void updateDescription(String description, boolean crumbFlag) throws IOEx params.put("core:apply", ""); params.put("Submit", "Save"); client.post_form(this.getUrl() + "/configSubmit?", params, crumbFlag); + return this; } /** @@ -259,8 +262,8 @@ public void updateDescription(String description, boolean crumbFlag) throws IOEx * @param description The description which should be set. * @throws IOException in case of errors. */ - public void updateDescription(String description) throws IOException { - updateDescription(description, false); + public BuildWithDetails updateDescription(String description) throws IOException { + return updateDescription(description, false); } private boolean isNullOrEmpty(String value) { @@ -479,8 +482,9 @@ public BuildChangeSet getChangeSet() { return result; } - public void setChangeSet(BuildChangeSet changeSet) { + public BuildWithDetails setChangeSet(BuildChangeSet changeSet) { this.changeSet = changeSet; + return this; } /** @@ -501,20 +505,23 @@ public List getChangeSets() { return result; } - public void setChangeSets(List changeSets) { + public BuildWithDetails setChangeSets(List changeSets) { this.changeSets = changeSets; + return this; } public List getCulprits() { return culprits; } - public void setCulprits(List culprits) { + public BuildWithDetails setCulprits(List culprits) { this.culprits = culprits; + return this; } - public void setResult(BuildResult result) { + public BuildWithDetails setResult(BuildResult result) { this.result = result; + return this; } public InputStream downloadArtifact(Artifact a) throws IOException, URISyntaxException { diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/CauseAction.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/CauseAction.java index e481f03a..dd455b50 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/CauseAction.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/CauseAction.java @@ -9,24 +9,27 @@ public String getShortDescription() { return shortDescription; } - public void setShortDescription(String shortDescription) { + public CauseAction setShortDescription(String shortDescription) { this.shortDescription = shortDescription; + return this; } public String getUserId() { return userId; } - public void setUserId(String userId) { + public CauseAction setUserId(String userId) { this.userId = userId; + return this; } public String getUserName() { return userName; } - public void setUserName(String userName) { + public CauseAction setUserName(String userName) { this.userName = userName; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Computer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Computer.java index 75f63af9..2414f061 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Computer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Computer.java @@ -10,6 +10,7 @@ import java.util.List; import com.offbytwo.jenkins.client.util.EncodingUtils; +import com.fasterxml.jackson.annotation.JsonProperty; /** * @author Kelly Plummer @@ -19,17 +20,20 @@ public class Computer extends BaseModel { private String displayName; - public List getComputers() { - return computer; - } + private List computers; - public void setComputer(List computer) { - this.computer = computer; + public Computer() { } - List computer; + @JsonProperty("computer") + public List getComputers() { + return computers; + } - public Computer() { + @JsonProperty("computer") + public Computer setComputers(List computers) { + this.computers = computers; + return this; } public Computer(String displayName) { @@ -65,10 +69,10 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; Computer other = (Computer) obj; - if (computer == null) { - if (other.computer != null) + if (computers == null) { + if (other.computers != null) return false; - } else if (!computer.equals(other.computer)) + } else if (!computers.equals(other.computers)) return false; if (displayName == null) { if (other.displayName != null) @@ -82,7 +86,7 @@ public boolean equals(Object obj) { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((computer == null) ? 0 : computer.hashCode()); + result = prime * result + ((computers == null) ? 0 : computers.hashCode()); result = prime * result + ((displayName == null) ? 0 : displayName.hashCode()); return result; } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerSet.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerSet.java index ef2e2047..0c12ba5a 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerSet.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerSet.java @@ -24,24 +24,27 @@ public int getBusyExecutors() { return busyExecutors; } - public void setBusyExecutors(int busyExecutors) { + public ComputerSet setBusyExecutors(int busyExecutors) { this.busyExecutors = busyExecutors; + return this; } public String getDisplayName() { return displayName; } - public void setDisplayName(String displayName) { + public ComputerSet setDisplayName(String displayName) { this.displayName = displayName; + return this; } public int getTotalExecutors() { return totalExecutors; } - public void setTotalExecutors(int totalExecutors) { + public ComputerSet setTotalExecutors(int totalExecutors) { this.totalExecutors = totalExecutors; + return this; } public List getComputers() { @@ -51,8 +54,9 @@ public List getComputers() { }).collect(Collectors.toList()); } - public void setComputer(List computers) { + public ComputerSet setComputer(List computers) { this.computer = computers; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java index 46958e6f..2ee6a55b 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java @@ -33,6 +33,7 @@ public class ComputerWithDetails extends Computer { public ComputerWithDetails() { } + @Override public String getDisplayName() { return displayName; } @@ -78,7 +79,7 @@ public LoadStatistics getLoadStatistics() throws IOException { return client.get("/computer/" + name + "/" + "loadStatistics/?depth=2", LoadStatistics.class); } - public void toggleOffline(boolean crumbFlag) throws IOException { + public ComputerWithDetails toggleOffline(boolean crumbFlag) throws IOException { // curl --data "json=init" -X POST "http://192.168.99.100:8080/computer/(master)/toggleOffline" String name; if ("master".equals(displayName)) { @@ -88,27 +89,28 @@ public void toggleOffline(boolean crumbFlag) throws IOException { } client.post( "/computer/" + name + "/toggleOffline", crumbFlag); + return this; } - public void toggleOffline() throws IOException { - toggleOffline( false ); + public ComputerWithDetails toggleOffline() throws IOException { + return toggleOffline(false); } - public void changeOfflineCause(String cause, boolean crumbFlag) throws IOException { + public ComputerWithDetails changeOfflineCause(String cause, boolean crumbFlag) throws IOException { String name; if ("master".equals(displayName)) { name = "(master)"; } else { name = EncodingUtils.encode(displayName); } - - Map data = new HashMap(); - data.put( "offlineMessage", cause ); - client.post_form("/computer/" + name + "/changeOfflineCause?", data, crumbFlag); + Map data = new HashMap(); + data.put("offlineMessage", cause); + client.post_form("/computer/" + name + "/changeOfflineCause?", data, crumbFlag); + return this; } - public void changeOfflineCause(String cause) throws IOException { - changeOfflineCause(cause, false); + public ComputerWithDetails changeOfflineCause(String cause) throws IOException { + return changeOfflineCause(cause, false); } public Boolean getManualLaunchAllowed() { diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ConsoleLog.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ConsoleLog.java index 59ef5c6d..503e1ce0 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ConsoleLog.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ConsoleLog.java @@ -19,23 +19,26 @@ public String getConsoleLog() { return consoleLog; } - public void setConsoleLog(String consoleLog) { + public ConsoleLog setConsoleLog(String consoleLog) { this.consoleLog = consoleLog; + return this; } public Boolean getHasMoreData() { return hasMoreData; } - public void setHasMoreData(Boolean hasMoreData) { + public ConsoleLog setHasMoreData(Boolean hasMoreData) { this.hasMoreData = hasMoreData; + return this; } public Integer getCurrentBufferSize() { return currentBufferSize; } - public void setCurrentBufferSize(Integer currentBufferSize) { + public ConsoleLog setCurrentBufferSize(Integer currentBufferSize) { this.currentBufferSize = currentBufferSize; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Executable.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Executable.java index ff1b6e27..5f044e13 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Executable.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Executable.java @@ -9,16 +9,18 @@ public Long getNumber() { return number; } - public void setNumber(Long number) { + public Executable setNumber(Long number) { this.number = number; + return this; } public String getUrl() { return url; } - public void setUrl(String url) { + public Executable setUrl(String url) { this.url = url; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Executor.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Executor.java index 15fcebde..c6914d97 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Executor.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Executor.java @@ -23,48 +23,54 @@ public Job getCurrentExecutable() { return currentExecutable; } - public void setCurrentExecutable(Job currentExecutable) { + public Executor setCurrentExecutable(Job currentExecutable) { this.currentExecutable = currentExecutable; + return this; } public Job getCurrentWorkUnit() { return currentWorkUnit; } - public void setCurrentWorkUnit(Job currentWorkUnit) { + public Executor setCurrentWorkUnit(Job currentWorkUnit) { this.currentWorkUnit = currentWorkUnit; + return this; } public Boolean getIdle() { return idle; } - public void setIdle(Boolean idle) { + public Executor setIdle(Boolean idle) { this.idle = idle; + return this; } public Boolean getLikelyStuck() { return likelyStuck; } - public void setLikelyStuck(Boolean likelyStuck) { + public Executor setLikelyStuck(Boolean likelyStuck) { this.likelyStuck = likelyStuck; + return this; } public int getNumber() { return number; } - public void setNumber(int number) { + public Executor setNumber(int number) { this.number = number; + return this; } public int getProgress() { return progress; } - public void setProgress(int progress) { + public Executor setProgress(int progress) { this.progress = progress; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ExtractHeader.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ExtractHeader.java index cb3c683a..6dd43221 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ExtractHeader.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ExtractHeader.java @@ -4,8 +4,9 @@ public class ExtractHeader extends BaseModel { private String location; - public void setLocation(String value) { + public ExtractHeader setLocation(String value) { location = value; + return this; } public String getLocation() { diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/FolderJob.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/FolderJob.java index a2ce89dc..f2677081 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/FolderJob.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/FolderJob.java @@ -79,8 +79,8 @@ public Job getJob(String name) { * @param folderName name of the folder to be created. * @throws IOException in case of an error. */ - public void createFolder(String folderName) throws IOException { - createFolder(folderName, false); + public FolderJob createFolder(String folderName) throws IOException { + return createFolder(folderName, false); } /** @@ -88,9 +88,10 @@ public void createFolder(String folderName) throws IOException { * * @param folderName name of the folder to be created. * @param crumbFlag true/false. + * @return * @throws IOException in case of an error. */ - public void createFolder(String folderName, Boolean crumbFlag) throws IOException { + public FolderJob createFolder(String folderName, Boolean crumbFlag) throws IOException { // https://gist.github.com/stuart-warren/7786892 was slightly helpful // here //TODO: JDK9+: Map.of(...) @@ -100,6 +101,7 @@ public void createFolder(String folderName, Boolean crumbFlag) throws IOExceptio params.put("from", ""); params.put("Submit", "OK"); client.post_form(this.getUrl() + "/createItem?", params, crumbFlag); + return this; } /* diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/HourMinSec10.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/HourMinSec10.java index 0dba01dc..66823616 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/HourMinSec10.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/HourMinSec10.java @@ -15,24 +15,27 @@ public Statis getHour() { return hour; } - public void setHour(Statis hour) { + public HourMinSec10 setHour(Statis hour) { this.hour = hour; + return this; } public Statis getMin() { return min; } - public void setMin(Statis min) { + public HourMinSec10 setMin(Statis min) { this.min = min; + return this; } public Statis getSec10() { return sec10; } - public void setSec10(Statis sec10) { + public HourMinSec10 setSec10(Statis sec10) { this.sec10 = sec10; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JacocoCoverageReport.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JacocoCoverageReport.java index ed623aa1..cc1345d5 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JacocoCoverageReport.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JacocoCoverageReport.java @@ -11,32 +11,46 @@ public class JacocoCoverageReport extends BaseModel { public JacocoCoverageResult getLineCoverage() { return lineCoverage; } - public void setLineCoverage(JacocoCoverageResult lineCoverage) { + + public JacocoCoverageReport setLineCoverage(JacocoCoverageResult lineCoverage) { this.lineCoverage = lineCoverage; + return this; } + public JacocoCoverageResult getClassCoverage() { return classCoverage; } - public void setClassCoverage(JacocoCoverageResult classCoverage) { + + public JacocoCoverageReport setClassCoverage(JacocoCoverageResult classCoverage) { this.classCoverage = classCoverage; + return this; } + public JacocoCoverageResult getComplexityScore() { return complexityScore; } - public void setComplexityScore(JacocoCoverageResult complexityScore) { + + public JacocoCoverageReport setComplexityScore(JacocoCoverageResult complexityScore) { this.complexityScore = complexityScore; + return this; } + public JacocoCoverageResult getInstructionCoverage() { return instructionCoverage; } - public void setInstructionCoverage(JacocoCoverageResult instructionCoverage) { + + public JacocoCoverageReport setInstructionCoverage(JacocoCoverageResult instructionCoverage) { this.instructionCoverage = instructionCoverage; + return this; } + public JacocoCoverageResult getBranchCoverage() { return branchCoverage; } - public void setBranchCoverage(JacocoCoverageResult branchCoverage) { + + public JacocoCoverageReport setBranchCoverage(JacocoCoverageResult branchCoverage) { this.branchCoverage = branchCoverage; + return this; } } \ No newline at end of file diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JacocoCoverageResult.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JacocoCoverageResult.java index 760bb610..41f3f43d 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JacocoCoverageResult.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JacocoCoverageResult.java @@ -11,34 +11,46 @@ public class JacocoCoverageResult { public int getCovered() { return covered; } - public void setCovered(int covered) { + + public JacocoCoverageResult setCovered(int covered) { this.covered = covered; + return this; } + public int getMissed() { return missed; } - public void setMissed(int missed) { + + public JacocoCoverageResult setMissed(int missed) { this.missed = missed; + return this; } + public int getPercentage() { return percentage; } - public void setPercentage(int percentage) { + + public JacocoCoverageResult setPercentage(int percentage) { this.percentage = percentage; + return this; } + public int getPercentageFloat() { return percentageFloat; } - public void setPercentageFloat(int percentageFloat) { + + public JacocoCoverageResult setPercentageFloat(int percentageFloat) { this.percentageFloat = percentageFloat; + return this; } + public int getTotal() { return total; } - public void setTotal(int total) { + + public JacocoCoverageResult setTotal(int total) { this.total = total; + return this; } - - } \ No newline at end of file diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobConfiguration.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobConfiguration.java index 571430ab..d6a95050 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobConfiguration.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobConfiguration.java @@ -77,7 +77,8 @@ public String getConfigXml() { return configXml; } - public void setConfigXml(String configXml) { + public JobConfiguration setConfigXml(String configXml) { this.configXml = configXml; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java index 71bc664a..b5894015 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java @@ -471,8 +471,8 @@ public Optional getBuildByNumber(final int buildNumber) { * {@link #EMPTY_DESCRIPTION}. * @throws IOException in case of errors. */ - public void updateDescription(String description) throws IOException { - updateDescription(description, false); + public JobWithDetails updateDescription(String description) throws IOException { + return updateDescription(description, false); } /** @@ -484,13 +484,14 @@ public void updateDescription(String description) throws IOException { * @param crumbFlag true or false. * @throws IOException in case of errors. */ - public void updateDescription(String description, boolean crumbFlag) throws IOException { + public JobWithDetails updateDescription(String description, boolean crumbFlag) throws IOException { Objects.requireNonNull(description, "description is not allowed to be null."); //JDK9+ // Map.of(...); Map params = new HashMap<>(); params.put("description", description); client.post_form(this.getUrl() + "/submitDescription?", params, crumbFlag); + return this; } /** @@ -498,8 +499,8 @@ public void updateDescription(String description, boolean crumbFlag) throws IOEx * * @throws IOException in case of errors. */ - public void clearDescription() throws IOException { - updateDescription(EMPTY_DESCRIPTION); + public JobWithDetails clearDescription() throws IOException { + return updateDescription(EMPTY_DESCRIPTION); } /** @@ -508,8 +509,8 @@ public void clearDescription() throws IOException { * @param crumbFlag true or false. * @throws IOException in case of errors. */ - public void clearDescription(boolean crumbFlag) throws IOException { - updateDescription(EMPTY_DESCRIPTION, crumbFlag); + public JobWithDetails clearDescription(boolean crumbFlag) throws IOException { + return updateDescription(EMPTY_DESCRIPTION, crumbFlag); } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/LoadStatistics.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/LoadStatistics.java index df2a5608..fc335e5e 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/LoadStatistics.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/LoadStatistics.java @@ -18,24 +18,27 @@ public HourMinSec10 getBusyExecutors() { return busyExecutors; } - public void setBusyExecutors(HourMinSec10 busyExecutors) { + public LoadStatistics setBusyExecutors(HourMinSec10 busyExecutors) { this.busyExecutors = busyExecutors; + return this; } public HourMinSec10 getQueueLength() { return queueLength; } - public void setQueueLength(HourMinSec10 queueLength) { + public LoadStatistics setQueueLength(HourMinSec10 queueLength) { this.queueLength = queueLength; + return this; } public HourMinSec10 getTotalExecutors() { return totalExecutors; } - public void setTotalExecutors(HourMinSec10 totalExecutors) { + public LoadStatistics setTotalExecutors(HourMinSec10 totalExecutors) { this.totalExecutors = totalExecutors; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MainView.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MainView.java index bef07f0b..167f6f40 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MainView.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MainView.java @@ -33,15 +33,17 @@ public List getJobs() { return jobs; } - public void setJobs(List jobs) { + public MainView setJobs(List jobs) { this.jobs = jobs; + return this; } public List getViews() { return views; } - public void setViews(List views) { + public MainView setViews(List views) { this.views = views; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenArtifact.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenArtifact.java index 184ccc37..c51ea4ea 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenArtifact.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenArtifact.java @@ -18,63 +18,71 @@ public String getArtifactId() { return artifactId; } - public void setArtifactId(String artifactId) { + public MavenArtifact setArtifactId(String artifactId) { this.artifactId = artifactId; + return this; } public String getCanonicalName() { return canonicalName; } - public void setCanonicalName(String canonicalName) { + public MavenArtifact setCanonicalName(String canonicalName) { this.canonicalName = canonicalName; + return this; } public String getClassifier() { return classifier; } - public void setClassifier(String classifier) { + public MavenArtifact setClassifier(String classifier) { this.classifier = classifier; + return this; } public String getFileName() { return fileName; } - public void setFileName(String fileName) { + public MavenArtifact setFileName(String fileName) { this.fileName = fileName; + return this; } public String getGroupId() { return groupId; } - public void setGroupId(String groupId) { + public MavenArtifact setGroupId(String groupId) { this.groupId = groupId; + return this; } public String getMd5sum() { return md5sum; } - public void setMd5sum(String md5sum) { + public MavenArtifact setMd5sum(String md5sum) { this.md5sum = md5sum; + return this; } public String getType() { return type; } - public void setType(String type) { + public MavenArtifact setType(String type) { this.type = type; + return this; } public String getVersion() { return version; } - public void setVersion(String version) { + public MavenArtifact setVersion(String version) { this.version = version; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModuleRecord.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModuleRecord.java index 3684c21d..34fbd424 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModuleRecord.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModuleRecord.java @@ -17,39 +17,44 @@ public List getAttachedArtifacts() { return attachedArtifacts; } - public void setAttachedArtifacts(List attachedArtifacts) { + public MavenModuleRecord setAttachedArtifacts(List attachedArtifacts) { this.attachedArtifacts = attachedArtifacts; + return this; } public Build getParent() { return parent; } - public void setParent(Build parent) { + public MavenModuleRecord setParent(Build parent) { this.parent = parent; + return this; } public MavenArtifact getMainArtifact() { return mainArtifact; } - public void setMainArtifact(MavenArtifact mainArtifact) { + public MavenModuleRecord setMainArtifact(MavenArtifact mainArtifact) { this.mainArtifact = mainArtifact; + return this; } public MavenArtifact getPomArtifact() { return pomArtifact; } - public void setPomArtifact(MavenArtifact pomArtifact) { + public MavenModuleRecord setPomArtifact(MavenArtifact pomArtifact) { this.pomArtifact = pomArtifact; + return this; } public String getUrl() { return url; } - public void setUrl(String url) { + public MavenModuleRecord setUrl(String url) { this.url = url; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/OfflineCause.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/OfflineCause.java index 66c70cd1..30969dc9 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/OfflineCause.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/OfflineCause.java @@ -17,6 +17,16 @@ public String getDescription() { return description; } + public OfflineCause setTimestamp(Long timestamp) { + this.timestamp = timestamp; + return this; + } + + public OfflineCause setDescription(String description) { + this.description = description; + return this; + } + @Override public int hashCode() { final int prime = 31; @@ -48,12 +58,4 @@ public boolean equals(Object obj) { return true; } - public void setTimestamp(Long timestamp) { - this.timestamp = timestamp; - } - - public void setDescription(String description) { - this.description = description; - } - } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ParameterDefinitions.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ParameterDefinitions.java index b46c69e4..47247c74 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ParameterDefinitions.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ParameterDefinitions.java @@ -30,11 +30,13 @@ public List getStringParams() { return stringParams; } - public void setStringParams(List stringParams) { + public ParameterDefinitions setStringParams(List stringParams) { this.stringParams = stringParams; + return this; } - public void addParam(StringParameterDefinition spd) { + public ParameterDefinitions addParam(StringParameterDefinition spd) { stringParams.add(spd); + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ParametersDefinitionProperty.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ParametersDefinitionProperty.java index efb033f5..bb88a128 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ParametersDefinitionProperty.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ParametersDefinitionProperty.java @@ -26,7 +26,8 @@ public ParameterDefinitions getPd() { return pd; } - public void setPd(ParameterDefinitions pd) { + public ParametersDefinitionProperty setPd(ParameterDefinitions pd) { this.pd = pd; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Plugin.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Plugin.java index fe380202..6c9e09a1 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Plugin.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Plugin.java @@ -27,9 +27,10 @@ public boolean isActive() return active; } - public void setActive( boolean active ) + public Plugin setActive(boolean active) { this.active = active; + return this; } public String getBackupVersion() @@ -37,9 +38,10 @@ public String getBackupVersion() return backupVersion; } - public void setBackupVersion( String backupVersion ) + public Plugin setBackupVersion(String backupVersion) { this.backupVersion = backupVersion; + return this; } public boolean isBundled() @@ -47,9 +49,10 @@ public boolean isBundled() return bundled; } - public void setBundled( boolean bundled ) + public Plugin setBundled(boolean bundled) { this.bundled = bundled; + return this; } public boolean isDowngradable() @@ -57,9 +60,10 @@ public boolean isDowngradable() return downgradable; } - public void setDowngradable( boolean downgradable ) + public Plugin setDowngradable(boolean downgradable) { this.downgradable = downgradable; + return this; } public boolean isEnabled() @@ -67,9 +71,10 @@ public boolean isEnabled() return enabled; } - public void setEnabled( boolean enabled ) + public Plugin setEnabled(boolean enabled) { this.enabled = enabled; + return this; } public boolean isHasUpdate() @@ -77,9 +82,10 @@ public boolean isHasUpdate() return hasUpdate; } - public void setHasUpdate( boolean hasUpdate ) + public Plugin setHasUpdate(boolean hasUpdate) { this.hasUpdate = hasUpdate; + return this; } public String getLongName() @@ -87,9 +93,10 @@ public String getLongName() return longName; } - public void setLongName( String longName ) + public Plugin setLongName(String longName) { this.longName = longName; + return this; } public boolean isPinned() @@ -97,9 +104,10 @@ public boolean isPinned() return pinned; } - public void setPinned( boolean pinned ) + public Plugin setPinned(boolean pinned) { this.pinned = pinned; + return this; } public String getShortName() @@ -107,9 +115,10 @@ public String getShortName() return shortName; } - public void setShortName( String shortName ) + public Plugin setShortName(String shortName) { this.shortName = shortName; + return this; } public String getSupportsDynamicLoad() @@ -117,9 +126,10 @@ public String getSupportsDynamicLoad() return supportsDynamicLoad; } - public void setSupportsDynamicLoad( String supportsDynamicLoad ) + public Plugin setSupportsDynamicLoad(String supportsDynamicLoad) { this.supportsDynamicLoad = supportsDynamicLoad; + return this; } public String getUrl() @@ -127,9 +137,10 @@ public String getUrl() return url; } - public void setUrl( String url ) + public Plugin setUrl(String url) { this.url = url; + return this; } public String getVersion() @@ -137,9 +148,10 @@ public String getVersion() return version; } - public void setVersion( String version ) + public Plugin setVersion(String version) { this.version = version; + return this; } public List getDependencies() @@ -147,9 +159,10 @@ public List getDependencies() return dependencies; } - public void setDependencies( List dependencies ) + public Plugin setDependencies(List dependencies) { this.dependencies = dependencies; + return this; } @Override @@ -247,6 +260,4 @@ else if ( !version.equals( other.version ) ) return true; } - - } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PluginDependency.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PluginDependency.java index adb1331d..acac798d 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PluginDependency.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PluginDependency.java @@ -11,6 +11,33 @@ public class PluginDependency extends BaseModel private String version; + public boolean isOptional() { + return optional; + } + + public PluginDependency setOptional(boolean optional) { + this.optional = optional; + return this; + } + + public String getShortName() { + return shortName; + } + + public PluginDependency setShortName(String shortName) { + this.shortName = shortName; + return this; + } + + public String getVersion() { + return version; + } + + public PluginDependency setVersion(String version) { + this.version = version; + return this; + } + @Override public int hashCode() { @@ -51,34 +78,4 @@ else if ( !version.equals( other.version ) ) return true; } - public boolean isOptional() - { - return optional; - } - - public void setOptional( boolean optional ) - { - this.optional = optional; - } - - public String getShortName() - { - return shortName; - } - - public void setShortName( String shortName ) - { - this.shortName = shortName; - } - - public String getVersion() - { - return version; - } - - public void setVersion( String version ) - { - this.version = version; - } - } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PluginManager.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PluginManager.java index f23ccaba..c08fc713 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PluginManager.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/PluginManager.java @@ -14,8 +14,9 @@ public List getPlugins() return plugins; } - public void setPlugins(List plugins) { + public PluginManager setPlugins(List plugins) { this.plugins = plugins; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Queue.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Queue.java index 3320ecb5..355dc910 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Queue.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Queue.java @@ -8,8 +8,7 @@ import java.util.List; -public class Queue - extends BaseModel +public class Queue extends BaseModel { private List discoverableItems; @@ -24,9 +23,10 @@ public List getDiscoverableItems() return discoverableItems; } - public void setDiscoverableItems( List discoverableItems ) + public Queue setDiscoverableItems(List discoverableItems) { this.discoverableItems = discoverableItems; + return this; } @Override @@ -44,9 +44,10 @@ public List getItems() return items; } - public void setItems( List items ) + public Queue setItems(List items) { this.items = items; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/QueueItem.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/QueueItem.java index 662b3e2b..ae2d8d3d 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/QueueItem.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/QueueItem.java @@ -38,48 +38,54 @@ public List getActions() { return actions; } - public void setActions(List actions) { + public QueueItem setActions(List actions) { this.actions = actions; + return this; } public boolean isBlocked() { return blocked; } - public void setBlocked(boolean blocked) { + public QueueItem setBlocked(boolean blocked) { this.blocked = blocked; + return this; } public boolean isBuildable() { return buildable; } - public void setBuildable(boolean buildable) { + public QueueItem setBuildable(boolean buildable) { this.buildable = buildable; + return this; } public Long getId() { return id; } - public void setId(Long id) { + public QueueItem setId(Long id) { this.id = id; + return this; } public Long getInQueueSince() { return inQueueSince; } - public void setInQueueSince(Long inQueueSince) { + public QueueItem setInQueueSince(Long inQueueSince) { this.inQueueSince = inQueueSince; + return this; } public String getParams() { return params; } - public void setParams(String params) { + public QueueItem setParams(String params) { this.params = params; + return this; } public boolean isStuck() { @@ -90,44 +96,50 @@ public QueueTask getTask() { return task; } - public void setTask(QueueTask task) { + public QueueItem setTask(QueueTask task) { this.task = task; + return this; } - public void setStuck(boolean stuck) { + public QueueItem setStuck(boolean stuck) { this.stuck = stuck; + return this; } public String getUrl() { return url; } - public void setUrl(String url) { + public QueueItem setUrl(String url) { this.url = url; + return this; } public String getWhy() { return why; } - public void setWhy(String why) { + public QueueItem setWhy(String why) { this.why = why; + return this; } public boolean isCancelled() { return cancelled; } - public void setCancelled(boolean cancelled) { + public QueueItem setCancelled(boolean cancelled) { this.cancelled = cancelled; + return this; } public Executable getExecutable() { return executable; } - public void setExecutable(Executable executable) { + public QueueItem setExecutable(Executable executable) { this.executable = executable; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/QueueItemActions.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/QueueItemActions.java index 4c49ba5f..cbd6e390 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/QueueItemActions.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/QueueItemActions.java @@ -15,8 +15,9 @@ public List getCauses() { return causes; } - public void setCauses(List causes) { + public QueueItemActions setCauses(List causes) { this.causes = causes; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Statis.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Statis.java index b2c601c3..bb920ea4 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Statis.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Statis.java @@ -22,16 +22,18 @@ public List getHistory() { return history; } - public void setHistory(List history) { + public Statis setHistory(List history) { this.history = history; + return this; } public Double getLatest() { return latest; } - public void setLatest(Double latest) { + public Statis setLatest(Double latest) { this.latest = latest; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/StringParameterDefinition.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/StringParameterDefinition.java index 740e3d77..2a89618f 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/StringParameterDefinition.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/StringParameterDefinition.java @@ -34,23 +34,26 @@ public String getName() { return name; } - public void setName(String name) { + public StringParameterDefinition setName(String name) { this.name = name; + return this; } public String getDescription() { return description; } - public void setDescription(String description) { + public StringParameterDefinition setDescription(String description) { this.description = description; + return this; } public String getDefaultValue() { return defaultValue; } - public void setDefaultValue(String defaultValue) { + public StringParameterDefinition setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; + return this; } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestCase.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestCase.java index 8f4f3795..f3ac1331 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestCase.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestCase.java @@ -21,9 +21,10 @@ public int getAge() return age; } - public void setAge( int age ) + public TestCase setAge(int age) { this.age = age; + return this; } public String getClassName() @@ -31,9 +32,10 @@ public String getClassName() return className; } - public void setClassName( String className ) + public TestCase setClassName(String className) { this.className = className; + return this; } public double getDuration() @@ -41,9 +43,10 @@ public double getDuration() return duration; } - public void setDuration( double duration ) + public TestCase setDuration(double duration) { this.duration = duration; + return this; } public int getFailedSince() @@ -51,9 +54,10 @@ public int getFailedSince() return failedSince; } - public void setFailedSince( int failedSince ) + public TestCase setFailedSince(int failedSince) { this.failedSince = failedSince; + return this; } public String getName() @@ -61,9 +65,10 @@ public String getName() return name; } - public void setName( String name ) + public TestCase setName(String name) { this.name = name; + return this; } public boolean isSkipped() @@ -71,9 +76,10 @@ public boolean isSkipped() return skipped; } - public void setSkipped( boolean skipped ) + public TestCase setSkipped(boolean skipped) { this.skipped = skipped; + return this; } public String getStatus() @@ -81,9 +87,10 @@ public String getStatus() return status; } - public void setStatus( String status ) + public TestCase setStatus(String status) { this.status = status; + return this; } public String getErrorDetails() @@ -91,9 +98,10 @@ public String getErrorDetails() return errorDetails; } - public void setErrorDetails( String errorDetails ) + public TestCase setErrorDetails(String errorDetails) { this.errorDetails = errorDetails; + return this; } public String getErrorStackTrace() @@ -101,9 +109,10 @@ public String getErrorStackTrace() return errorStackTrace; } - public void setErrorStackTrace( String errorStackTrace ) + public TestCase setErrorStackTrace(String errorStackTrace) { this.errorStackTrace = errorStackTrace; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestChild.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestChild.java index 516bb446..a8d50ca0 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestChild.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestChild.java @@ -12,16 +12,18 @@ public int getNumber() { return number; } - public void setNumber(int number) { + public TestChild setNumber(int number) { this.number = number; + return this; } public String getUrl() { return url; } - public void setUrl(String url) { + public TestChild setUrl(String url) { this.url = url; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestChildReport.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestChildReport.java index da920bec..7d3ea3f5 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestChildReport.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestChildReport.java @@ -13,8 +13,18 @@ public TestChild getChild() { return child; } - public void setChild(TestChild child) { + public TestChildReport setChild(TestChild child) { this.child = child; + return this; + } + + public TestResult getResult() { + return result; + } + + public TestChildReport setResult(TestResult result) { + this.result = result; + return this; } @Override @@ -48,12 +58,4 @@ public boolean equals(Object obj) { return true; } - public TestResult getResult() { - return result; - } - - public void setResult(TestResult result) { - this.result = result; - } - } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestReport.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestReport.java index b775c3f2..de3f0162 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestReport.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestReport.java @@ -47,40 +47,45 @@ public int getFailCount() { return failCount; } - public void setFailCount(int failCount) { + public TestReport setFailCount(int failCount) { this.failCount = failCount; + return this; } public int getSkipCount() { return skipCount; } - public void setSkipCount(int skipCount) { + public TestReport setSkipCount(int skipCount) { this.skipCount = skipCount; + return this; } public int getTotalCount() { return totalCount; } - public void setTotalCount(int totalCount) { + public TestReport setTotalCount(int totalCount) { this.totalCount = totalCount; + return this; } public String getUrlName() { return urlName; } - public void setUrlName(String urlName) { + public TestReport setUrlName(String urlName) { this.urlName = urlName; + return this; } public List getChildReports() { return childReports; } - public void setChildReports(List childReports) { + public TestReport setChildReports(List childReports) { this.childReports = childReports; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestResult.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestResult.java index 934b32d4..5dda306f 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestResult.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestResult.java @@ -20,40 +20,54 @@ public double getDuration() { return duration; } - public void setDuration(double duration) { + public TestResult setDuration(double duration) { this.duration = duration; + return this; } public boolean isEmpty() { return empty; } - public void setEmpty(boolean empty) { + public TestResult setEmpty(boolean empty) { this.empty = empty; + return this; } public int getFailCount() { return failCount; } - public void setFailCount(int failCount) { + public TestResult setFailCount(int failCount) { this.failCount = failCount; + return this; } public int getPassCount() { return passCount; } - public void setPassCount(int passCount) { + public TestResult setPassCount(int passCount) { this.passCount = passCount; + return this; } public int getSkipCount() { return skipCount; } - public void setSkipCount(int skipCount) { + public TestResult setSkipCount(int skipCount) { this.skipCount = skipCount; + return this; + } + + public List getSuites() { + return suites; + } + + public TestResult setSuites(List suites) { + this.suites = suites; + return this; } @Override @@ -97,12 +111,4 @@ public boolean equals(Object obj) { return false; return true; } - - public List getSuites() { - return suites; - } - - public void setSuites(List suites) { - this.suites = suites; - } } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestSuites.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestSuites.java index 45c96883..030b03b9 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestSuites.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/TestSuites.java @@ -19,40 +19,45 @@ public double getDuration() { return duration; } - public void setDuration(double duration) { + public TestSuites setDuration(double duration) { this.duration = duration; + return this; } public String getId() { return id; } - public void setId(String id) { + public TestSuites setId(String id) { this.id = id; + return this; } public String getName() { return name; } - public void setName(String name) { + public TestSuites setName(String name) { this.name = name; + return this; } public String getTimestamp() { return timestamp; } - public void setTimestamp(String timestamp) { + public TestSuites setTimestamp(String timestamp) { this.timestamp = timestamp; + return this; } public List getCases() { return cases; } - public void setCases(List cases) { + public TestSuites setCases(List cases) { this.cases = cases; + return this; } @Override diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/View.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/View.java index 5267e4f1..422cd5a4 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/View.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/View.java @@ -13,8 +13,9 @@ public String getName() { return name; } - public void setName(String name) { + public View setName(String name) { this.name = name; + return this; } public View() { @@ -24,16 +25,18 @@ public String getDescription() { return description; } - public void setDescription(String description) { + public View setDescription(String description) { this.description = description; + return this; } public String getUrl() { return url; } - public void setUrl(String url) { + public View setUrl(String url) { this.url = url; + return this; } @Override From 752c3b99a6288001cc199ccbfb39ce5124c1ba82 Mon Sep 17 00:00:00 2001 From: Jesper Terkelsen Date: Mon, 15 Apr 2019 20:39:19 +0200 Subject: [PATCH 50/68] JENKINS-56186 Support for showing node labels via java API (#388) This information is already available in the API call. --- ReleaseNotes.md | 11 ++++++ .../offbytwo/jenkins/model/ComputerLabel.java | 34 +++++++++++++++++++ .../jenkins/model/ComputerWithDetails.java | 10 ++++++ 3 files changed, 55 insertions(+) create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerLabel.java diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 7003cd77..62323e1c 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -54,6 +54,17 @@ Add the crumbFlag as the 2nd parameter of getConsoleOutputText method + * [JENKINS-56186][jissue-56186] + + Added labels to computers + + ```java + ComputerWithDetails computer = ... + for (ComputerLabel assignedLabel : computer.getAssignedLabels()) { + assignedLabel.getName() + } + ``` + ## Release 0.3.8 * [Fixed Issue 289][issue-289] diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerLabel.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerLabel.java new file mode 100644 index 00000000..e61ecd2d --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerLabel.java @@ -0,0 +1,34 @@ +package com.offbytwo.jenkins.model; + +public class ComputerLabel { + private String name; + + public String getName() { + return name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ComputerLabel other = (ComputerLabel) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } +} diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java index 2ee6a55b..c57b40a5 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/ComputerWithDetails.java @@ -18,6 +18,7 @@ public class ComputerWithDetails extends Computer { private String displayName; private List actions; //TODO: What kind of List? private List executors; + private List assignedLabels; private Boolean idle; private Boolean jnlp; private Boolean launchSupported; @@ -46,6 +47,10 @@ public List getExecutors() { return executors; } + public List getAssignedLabels() { + return assignedLabels; + } + public Boolean getIdle() { return idle; } @@ -169,6 +174,11 @@ public boolean equals(Object obj) { return false; } else if (!executors.equals(other.executors)) return false; + if (assignedLabels == null) { + if (other.assignedLabels != null) + return false; + } else if (!assignedLabels.equals(other.assignedLabels)) + return false; if (idle == null) { if (other.idle != null) return false; From 28beabd817ec954ae3ecbabe4f3b54ba26ae9eae Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Mon, 15 Apr 2019 20:44:05 +0200 Subject: [PATCH 51/68] Fixed links in ReleaseNotes.md file. --- ReleaseNotes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 62323e1c..2c5d22ba 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1131,6 +1131,8 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-244]: https://github.com/jenkinsci/java-client-api/issues/244 [issue-268]: https://github.com/jenkinsci/java-client-api/issues/268 [issue-289]: https://github.com/jenkinsci/java-client-api/issues/289 +[issue-282]: https://github.com/jenkinsci/java-client-api/issues/282 +[issue-291]: https://github.com/jenkinsci/java-client-api/issues/291 [issue-298]: https://github.com/jenkinsci/java-client-api/issues/298 [issue-301]: https://github.com/jenkinsci/java-client-api/issues/301 [issue-394]: https://github.com/jenkinsci/java-client-api/issues/394 @@ -1161,3 +1163,4 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [jissue-38823]: https://issues.jenkins-ci.org/browse/JENKINS-38823 [jissue-46445]: https://issues.jenkins-ci.org/browse/JENKINS-46445 [jissue-46472]: https://issues.jenkins-ci.org/browse/JENKINS-46472 +[jissue-56186]: https://issues.jenkins-ci.org/browse/JENKINS-56186 From a70da3ce5b18b1bc765720d116dbe144036621cf Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sat, 27 Apr 2019 21:24:55 +0200 Subject: [PATCH 52/68] Fixed typo. --- ReleaseNotes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 2c5d22ba..9343daa1 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -9,7 +9,7 @@ cause we do not rely on Guava anymore. So you can use the original artifact directly. * This results in a bumping of the version - number cause it a change which is breaking + number cause it is a change which is breaking with previous version 0.3.8. * [Fixed Issue 405][issue-405] From 52d9d99461f188ac7d1adaf8e431b2125b861e30 Mon Sep 17 00:00:00 2001 From: Li Yudong Date: Sun, 28 Apr 2019 21:32:00 +0800 Subject: [PATCH 53/68] Fix JENKINS-56585 change to post method (#391) * change get to post * add link to ReleaseNotes.md --- ReleaseNotes.md | 6 ++++++ .../src/main/java/com/offbytwo/jenkins/JenkinsServer.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 9343daa1..45fc71da 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -64,6 +64,11 @@ assignedLabel.getName() } ``` + + * [JENKINS-56585][jissue-56585] + + Change request method of `QuietDown()` to POST + ## Release 0.3.8 @@ -1164,3 +1169,4 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [jissue-46445]: https://issues.jenkins-ci.org/browse/JENKINS-46445 [jissue-46472]: https://issues.jenkins-ci.org/browse/JENKINS-46472 [jissue-56186]: https://issues.jenkins-ci.org/browse/JENKINS-56186 +[jissue-56585]: https://issues.jenkins-ci.org/browse/JENKINS-56585 diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java index e9973d59..01755baa 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/JenkinsServer.java @@ -660,7 +660,7 @@ public JenkinsServer addStringParam(String jobName, String name, String descript */ public JenkinsServer quietDown() throws IOException { try { - client.get("/quietDown/"); + client.post("/quietDown/"); } catch (org.apache.http.client.ClientProtocolException e) { LOGGER.error("quietDown()", e); } From 86c8081b7532199708d9545903181e3f252884d5 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sun, 28 Apr 2019 15:35:25 +0200 Subject: [PATCH 54/68] Reformatted Range.java --- .../com/offbytwo/jenkins/helper/Range.java | 155 +++++++++--------- 1 file changed, 80 insertions(+), 75 deletions(-) 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 8b70eb09..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,122 +16,127 @@ * The same as {0,N}. *
  • {N}: Just retrieve the N-th element. The same as {N,N+1}.
  • * - * + *

    * 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 { - public static final String CURLY_BRACKET_OPEN = "%7B"; // { - public static final String CURLY_BRACKET_CLOSE = "%7D"; // } + /** + * 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; private Range() { - this.from = null; - this.to = null; + this.from = null; + this.to = null; } private Range setFrom(int from) { - if (from < 0) { - throw new IllegalArgumentException("from value must be greater or equal null."); - } - this.from = new Integer(from); - return this; + if (from < 0) { + throw new IllegalArgumentException("from value must be greater or equal null."); + } + this.from = new Integer(from); + return this; } private Range setTo(int to) { - if (to < 0) { - throw new IllegalArgumentException("to must be greater or equal null."); - } - this.to = new Integer(to); - return this; + if (to < 0) { + throw new IllegalArgumentException("to must be greater or equal null."); + } + this.to = new Integer(to); + return this; } public String getRangeString() { - StringBuilder sb = new StringBuilder(); - sb.append(CURLY_BRACKET_OPEN); - if (this.from != null) { - sb.append(String.format("%d", this.from)); - } + StringBuilder sb = new StringBuilder(); + sb.append(CURLY_BRACKET_OPEN); + if (this.from != null) { + sb.append(String.format("%d", this.from)); + } - sb.append(','); + sb.append(','); - if (this.to != null) { - sb.append(String.format("%d", this.to)); - } + if (this.to != null) { + sb.append(String.format("%d", this.to)); + } - sb.append(CURLY_BRACKET_CLOSE); - return sb.toString(); + sb.append(CURLY_BRACKET_CLOSE); + return sb.toString(); } public static final class FromBuilder { - private Range range; - - public FromBuilder(Range range) { - this.range = range; - } - - public Range to(int t) { - this.range.setTo(t); - if (range.to <= range.from) { - throw new IllegalArgumentException("to must be greater than from"); - } - return this.range; - } - - public Range build() { - return this.range; - } + private Range range; + + public FromBuilder(Range range) { + this.range = range; + } + + public Range to(int t) { + this.range.setTo(t); + if (range.to <= range.from) { + throw new IllegalArgumentException("to must be greater than from"); + } + return this.range; + } + + public Range build() { + return this.range; + } } public static final class ToBuilder { - private Range range; + private Range range; - public ToBuilder(Range range) { - this.range = range; - } + public ToBuilder(Range range) { + this.range = range; + } - public Range build() { - return this.range; - } + public Range build() { + return this.range; + } } public static final class Builder { - private Range range; - - protected Builder() { - this.range = new Range(); - } - - public FromBuilder from(int f) { - this.range.setFrom(f); - return new FromBuilder(this.range); - } - - public ToBuilder to(int t) { - this.range.setTo(t); - return new ToBuilder(this.range); - } - - public Range only(int only) { - this.range.from = new Integer(only); - this.range.to = new Integer(only + 1); - return this.range; - } + private Range range; + + protected Builder() { + this.range = new Range(); + } + + public FromBuilder from(int f) { + this.range.setFrom(f); + return new FromBuilder(this.range); + } + + public ToBuilder to(int t) { + this.range.setTo(t); + return new ToBuilder(this.range); + } + + public Range only(int only) { + this.range.from = new Integer(only); + this.range.to = new Integer(only + 1); + return this.range; + } } public static Builder build() { - return new Builder(); + return new Builder(); } } \ No newline at end of file From c4f5953d3d4dda92cd946ad3bf2b811524c32da9 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Tue, 30 Apr 2019 17:04:28 +0200 Subject: [PATCH 55/68] Get rid of JUnit rules. --- .../offbytwo/jenkins/helper/RangeTest.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/jenkins-client/src/test/java/com/offbytwo/jenkins/helper/RangeTest.java b/jenkins-client/src/test/java/com/offbytwo/jenkins/helper/RangeTest.java index 5dcc9e38..b56aa467 100644 --- a/jenkins-client/src/test/java/com/offbytwo/jenkins/helper/RangeTest.java +++ b/jenkins-client/src/test/java/com/offbytwo/jenkins/helper/RangeTest.java @@ -6,13 +6,10 @@ package com.offbytwo.jenkins.helper; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import com.offbytwo.jenkins.helper.Range; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; /** *
      @@ -23,7 +20,7 @@ * The same as {0,N}. *
    • {N}: Just retrieve the N-th element. The same as {N,N+1}.
    • *
    - * + * * @author Karl Heinz Marbaise */ public class RangeTest { @@ -56,27 +53,24 @@ public void onlyGiven() { assertThat(r.getRangeString()).isEqualTo(getEscaped("3,4")); } - @Rule - public ExpectedException exception = ExpectedException.none(); - @Test public void toIsGivenLargerThanFromShouldResultInIllegalArgumentException() { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("to must be greater than from"); - Range.build().from(5).to(1); + assertThatIllegalArgumentException() + .isThrownBy(() -> Range.build().from(5).to(1)) + .withMessage("to must be greater than from"); } @Test public void fromGivenNegativeValueShouldResultInIllegalArgumentException() { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("from value must be greater or equal null."); - Range.build().from(-1); + assertThatIllegalArgumentException() + .isThrownBy(() -> Range.build().from(-1)) + .withMessage("from value must be greater or equal null."); } @Test public void fromGivenPositiveToNegativeValueShouldResultInIllegalArgumentException() { - exception.expect(IllegalArgumentException.class); - exception.expectMessage("to must be greater or equal null."); - Range.build().from(5).to(-1); + assertThatIllegalArgumentException() + .isThrownBy(() -> Range.build().from(5).to(-1)) + .withMessage("to must be greater or equal null."); } } From 5807954872d077645b87c8c06d5124938d846136 Mon Sep 17 00:00:00 2001 From: Jakub Zacek Date: Thu, 31 May 2018 08:48:08 +0200 Subject: [PATCH 56/68] Fixed #309 - Added better support for Maven Modules - slight modifications based on removement of Guava --- ReleaseNotes.md | 9 +- .../com/offbytwo/jenkins/model/BaseModel.java | 9 +- .../jenkins/model/BuildWithDetails.java | 11 ++ .../java/com/offbytwo/jenkins/model/Job.java | 7 +- .../jenkins/model/JobWithDetails.java | 19 +++- .../jenkins/model/MavenJobWithDetails.java | 8 +- .../offbytwo/jenkins/model/MavenModule.java | 51 ++++++++- .../jenkins/model/MavenModuleWithDetails.java | 105 ++++++++++++++++++ 8 files changed, 198 insertions(+), 21 deletions(-) create mode 100644 jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModuleWithDetails.java diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 45fc71da..e69a8019 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,12 @@ ## Release 0.4.0 (NOT RELEASED YET) + * [Fixed Issue 309][issue-309] + + * Added possibility to get mode detailed data from Maven Modules from Jobs/Builds + + Thanks for that to [Jakub Zacek](https://github.com/dawon). + * [Fixed Issue 395][issue-395] * Remove google guava lib @@ -187,7 +193,7 @@ Added new methods to JenkinsServer for stopping and restarting Jenkins. The methods are restart(Boolean crumbFlag), safeRestart(Boolean crumbFlag), exit(Boolean crumbFlag) and safeExit(Boolean crumbFlag) Thanks for that to [Chids](https://github.com/Chids-gs). - + ## Release 0.3.7 * Changed Eclipse Formatting configuration. @@ -1140,6 +1146,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-291]: https://github.com/jenkinsci/java-client-api/issues/291 [issue-298]: https://github.com/jenkinsci/java-client-api/issues/298 [issue-301]: https://github.com/jenkinsci/java-client-api/issues/301 +[issue-309]: https://github.com/jenkinsci/java-client-api/issues/309 [issue-394]: https://github.com/jenkinsci/java-client-api/issues/394 [issue-395]: https://github.com/jenkinsci/java-client-api/issues/395 [issue-396]: https://github.com/jenkinsci/java-client-api/issues/396 diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java index 9c850ba2..5275d36b 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/BaseModel.java @@ -7,6 +7,7 @@ package com.offbytwo.jenkins.model; import com.offbytwo.jenkins.client.JenkinsHttpConnection; +import java.util.function.Predicate; /** * The base model. @@ -17,8 +18,7 @@ public class BaseModel { * The class. */ private String _class; - - + /** * Get the class. * @return class @@ -47,4 +47,9 @@ public BaseModel setClient(final JenkinsHttpConnection client) { this.client = client; return this; } + + protected static Predicate isBuildNumberEqualTo(int buildNumber) { + return build -> build.getNumber() == buildNumber; + } + } 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 ab9e201d..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 @@ -533,6 +533,17 @@ public InputStream downloadArtifact(Artifact a) throws IOException, URISyntaxExc ""); return client.getFile(artifactUri); } + + /** + * Returns {@link MavenModuleWithDetails} based on its name + * + * @param name module name + * @return {@link MavenModuleWithDetails} + * @throws IOException in case of error. + */ + public MavenModuleWithDetails getModule(String name) throws IOException { + return client.get(getUrl() + name, MavenModuleWithDetails.class); + } @Override public boolean equals(Object obj) { diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Job.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Job.java index ba1968a1..7d5313fd 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Job.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/Job.java @@ -6,16 +6,13 @@ package com.offbytwo.jenkins.model; -import static org.apache.commons.lang.StringUtils.join; - +import com.offbytwo.jenkins.client.util.EncodingUtils; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.Map; - -import com.offbytwo.jenkins.client.util.EncodingUtils; import java.util.function.Function; import java.util.stream.Collectors; @@ -186,4 +183,6 @@ public String apply(Map.Entry entry) { return EncodingUtils.formParameter(entry.getKey()) + "=" + EncodingUtils.formParameter(entry.getValue()); } } + + } diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java index b5894015..f13903cf 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/JobWithDetails.java @@ -18,7 +18,6 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.function.Predicate; import static com.offbytwo.jenkins.helper.FunctionalHelper.SET_CLIENT; import static java.util.stream.Collectors.toList; @@ -31,7 +30,7 @@ public class JobWithDetails extends Job { private boolean buildable; - private List builds; + private List builds = Collections.emptyList(); private Build firstBuild; @@ -438,10 +437,6 @@ public List getUpstreamProjects() { } } - private static Predicate isBuildNumberEqualTo(int buildNumber) { - return build -> build.getNumber() == buildNumber; - } - public QueueItem getQueueItem() { return this.queueItem; } @@ -456,6 +451,18 @@ public QueueItem getQueueItem() { public Optional getBuildByNumber(final int buildNumber) { return builds.stream().filter(isBuildNumberEqualTo(buildNumber)).findFirst(); } + + /** + * Get a module of a {@link Job} + * + * @param moduleName name of the {@link MavenModule} + * @return The {@link MavenModuleWithDetails} selected by the given module name + * @throws java.io.IOException in case of errors. + * + */ + public MavenModuleWithDetails getModule(String moduleName) throws IOException { + return client.get(getUrl() + moduleName, MavenModuleWithDetails.class); + } /** * Empty description to be used for {@link #updateDescription(String)} or diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenJobWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenJobWithDetails.java index bb3f0c62..3eaf7fc0 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenJobWithDetails.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenJobWithDetails.java @@ -1,7 +1,6 @@ package com.offbytwo.jenkins.model; import com.offbytwo.jenkins.client.util.EncodingUtils; -import com.offbytwo.jenkins.helper.FunctionalHelper; import com.offbytwo.jenkins.helper.Range; import org.apache.http.HttpStatus; import org.apache.http.client.HttpResponseException; @@ -10,7 +9,6 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.function.Predicate; import static com.offbytwo.jenkins.helper.FunctionalHelper.SET_CLIENT; import static java.util.stream.Collectors.toList; @@ -276,11 +274,7 @@ public List getUpstreamProjects() { } } - private static Predicate isBuildNumberEqualTo(int buildNumber) { - return build -> build.getNumber() == buildNumber; - } - - /** + /** * @param buildNumber The build you would like to select. * @return Optional which contains the {@link MavenBuild}. */ diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModule.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModule.java index 07c61bb1..91c7ef1c 100644 --- a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModule.java +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModule.java @@ -1,10 +1,59 @@ +/* + * Copyright (c) 2018 Cosmin Stejerean, Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ package com.offbytwo.jenkins.model; +import java.io.IOException; import java.util.List; - +/** + * + * @author Karl Heinz Marbaise, Ricardo Zanini, René Scheibe, Jakub Zacek + */ public class MavenModule extends BaseModel { private List moduleRecords; + private String name; + private String url; + private String color; + private String displayName; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public MavenModuleWithDetails details() throws IOException { + return client.get(url, MavenModuleWithDetails.class); + } public List getModuleRecords() { return moduleRecords; diff --git a/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModuleWithDetails.java b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModuleWithDetails.java new file mode 100644 index 00000000..d168a45e --- /dev/null +++ b/jenkins-client/src/main/java/com/offbytwo/jenkins/model/MavenModuleWithDetails.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018 Cosmin Stejerean, Karl Heinz Marbaise, and contributors. + * + * Distributed under the MIT license: http://opensource.org/licenses/MIT + */ +package com.offbytwo.jenkins.model; + +import static com.offbytwo.jenkins.helper.FunctionalHelper.SET_CLIENT; +import static java.util.stream.Collectors.toList; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Model Class for Maven Modules + * + * @author Jakub Zacek + */ +public class MavenModuleWithDetails extends BaseModel { + + private List builds = Collections.emptyList(); + private List actions = Collections.emptyList(); + private String displayName; + private BuildResult result; + private String url; + private long duration; + private long timestamp; + + public List getActions() { + return actions; + } + + public void setActions(List actions) { + this.actions = actions; + } + + public void setBuilds(List builds) { + this.builds = builds; + } + + public List getBuilds() { + return builds.stream() + .map(SET_CLIENT(this.getClient())) + .collect(toList()); + } + + public Build getBuildByNumber(final int buildNumber) { + return builds.stream() + .filter(isBuildNumberEqualTo(buildNumber)) + .map(SET_CLIENT(this.getClient())) + .findFirst() + .orElse(Build.BUILD_HAS_NEVER_RUN); + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public BuildResult getResult() { + return result; + } + + public void setResult(BuildResult result) { + this.result = result; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public String getConsoleOutputText() throws IOException { + return client.get(getUrl() + "/logText/progressiveText"); + } + + public TestReport getTestReport() throws IOException { + return client.get(this.getUrl() + "/testReport/?depth=1", TestReport.class); + } + +} From 99895b2c055bd44a5110ec7662be96c46e3a591b Mon Sep 17 00:00:00 2001 From: based2 Date: Fri, 31 May 2019 13:57:38 +0200 Subject: [PATCH 57/68] update jackson from 2.9.8 to 2.9.9 CVE-2019-12086 (#411) https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.9.9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8015cefa..287a3ec9 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ 4.5.8 4.4.11 4.5.8 - 2.9.8 + 2.9.9 From 775ef812f8af35ad73c021287e138c6258518734 Mon Sep 17 00:00:00 2001 From: based2 Date: Fri, 31 May 2019 13:58:07 +0200 Subject: [PATCH 58/68] update commons-lang from 3.8.1 to 3.9 (#412) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 287a3ec9..06911f60 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 2.4 1.4.7-jenkins-1 1.6.1 - 3.8.1 + 3.9 2.4 4.5.8 4.4.11 From e1285835fcbdd43766b3e8e1626f6f3626a15035 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sat, 14 Sep 2019 15:02:53 +0200 Subject: [PATCH 59/68] Fixed #424 - Upgrade Maven Plugins --- pom.xml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index 06911f60..ffa639db 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ true true - 1.5.3 + 1.6.0 1.644 @@ -165,7 +165,7 @@ org.testng testng - 6.14.2 + 7.0.0 test @@ -224,7 +224,7 @@ org.apache.maven.plugins maven-help-plugin - 3.1.1 + 3.2.0 org.apache.maven.plugins @@ -239,7 +239,7 @@ org.apache.maven.plugins maven-source-plugin - 3.0.1 + 3.1.0 1.644 4.12 - 1.9.5 + 3.0.0 2.4 1.4.7-jenkins-1 1.6.1 @@ -166,33 +166,35 @@ org.testng testng 7.0.0 - test + + + org.junit + junit-bom + 5.5.2 + import + pom junit junit ${junit.version} - test org.mockito mockito-core ${mockito-core.version} - test org.jenkins-ci.main jenkins-test-harness ${jenkins-version} - test org.assertj assertj-core 3.12.2 - test @@ -202,13 +204,10 @@ org.apache.logging.log4j - log4j-core - 2.11.1 - - - org.apache.logging.log4j - log4j-slf4j-impl - 2.11.1 + log4j-bom + 2.12.1 + import + pom xml-apis From fe2601a77733887a0cdfa4d20d46997765e8e8ca Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sat, 14 Sep 2019 15:27:34 +0200 Subject: [PATCH 61/68] Fixed #426 - Upgrade dom4j --- jenkins-client/pom.xml | 2 +- pom.xml | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/jenkins-client/pom.xml b/jenkins-client/pom.xml index ea595a4d..b70b08fc 100644 --- a/jenkins-client/pom.xml +++ b/jenkins-client/pom.xml @@ -34,7 +34,7 @@ - dom4j + org.dom4j dom4j diff --git a/pom.xml b/pom.xml index 68704676..98ee517d 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,6 @@ 3.0.0 2.4 1.4.7-jenkins-1 - 1.6.1 3.9 2.4 4.5.8 @@ -105,9 +104,9 @@
    - dom4j + org.dom4j dom4j - ${dom4j.version} + 2.1.1 From fc3b0e38179ac2ff435bfd529d2fa3841e2f2bef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2020 15:14:10 +0200 Subject: [PATCH 62/68] Bump jackson-databind.version from 2.9.9 to 2.10.3 (#450) Bumps `jackson-databind.version` from 2.9.9 to 2.10.3. Updates `jackson-annotations` from 2.9.9 to 2.10.3 - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) Updates `jackson-core` from 2.9.9 to 2.10.3 - [Release notes](https://github.com/FasterXML/jackson-core/releases) - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.9.9...jackson-core-2.10.3) Updates `jackson-databind` from 2.9.9 to 2.10.3 - [Release notes](https://github.com/FasterXML/jackson/releases) - [Commits](https://github.com/FasterXML/jackson/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 98ee517d..821999a0 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ 4.5.8 4.4.11 4.5.8 - 2.9.9 + 2.10.3 From 1a744770112f79708b3e3ea3106c324be4679374 Mon Sep 17 00:00:00 2001 From: Jonathan Leitschuh Date: Thu, 16 Apr 2020 09:25:27 -0400 Subject: [PATCH 63/68] Use HTTPS instead of HTTP to resolve dependencies (#448) This fixes a security vulnerability in this project where the `pom.xml` files were configuring Maven to resolve dependencies over HTTP instead of HTTPS. Signed-off-by: Jonathan Leitschuh --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 821999a0..bfa5d307 100644 --- a/pom.xml +++ b/pom.xml @@ -477,7 +477,7 @@ repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ + https://repo.jenkins-ci.org/public/ From 5ac251377875083027d5e54c0e611f6b59deb335 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sun, 3 May 2020 00:29:01 +0200 Subject: [PATCH 64/68] Added Funding. --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..5b8d5402 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [khmarbaise] \ No newline at end of file From 0376def0c01f2f7c91b8b3a544fab5c623b7be9a Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Mon, 27 Jul 2020 19:09:34 +0200 Subject: [PATCH 65/68] Fixed #464 - Migrate from xml-apis to xerces:xmlParserAPI --- ReleaseNotes.md | 5 +++++ jenkins-client/pom.xml | 5 ++--- pom.xml | 6 +++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ReleaseNotes.md b/ReleaseNotes.md index e69a8019..7847f3a9 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,10 @@ ## Release 0.4.0 (NOT RELEASED YET) + * [Fixed Issue 464][issue-464] + + * Replaced xml-apis with xerces-xmlParserAPI. + * [Fixed Issue 309][issue-309] * Added possibility to get mode detailed data from Maven Modules from Jobs/Builds @@ -1156,6 +1160,7 @@ TestReport testReport = mavenJob.getLastSuccessfulBuild().getTestReport(); [issue-401]: https://github.com/jenkinsci/java-client-api/issues/401 [issue-402]: https://github.com/jenkinsci/java-client-api/issues/402 [issue-405]: https://github.com/jenkinsci/java-client-api/issues/405 +[issue-464]: https://github.com/jenkinsci/java-client-api/issues/464 [pull-123]: https://github.com/jenkinsci/java-client-api/pull/123 [pull-149]: https://github.com/jenkinsci/java-client-api/pull/149 [pull-158]: https://github.com/jenkinsci/java-client-api/pull/158 diff --git a/jenkins-client/pom.xml b/jenkins-client/pom.xml index b70b08fc..2cbc3df9 100644 --- a/jenkins-client/pom.xml +++ b/jenkins-client/pom.xml @@ -109,10 +109,9 @@ assertj-core test - - xml-apis - xml-apis + xerces + xmlParserAPIs diff --git a/pom.xml b/pom.xml index bfa5d307..25ea5774 100644 --- a/pom.xml +++ b/pom.xml @@ -209,9 +209,9 @@ pom - xml-apis - xml-apis - 1.4.01 + xerces + xmlParserAPIs + 2.6.1 From 182fb4144862c956e0b199cc56d3ee83ab610dba Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Mon, 27 Jul 2020 19:29:10 +0200 Subject: [PATCH 66/68] Fixed #465 - Remove asciidoctor site parts --- ReleaseNotes.md | 5 +++++ jenkins-client/src/site/asciidoc/index.adoc | 7 ------- jenkins-client/src/site/asciidoc/sub/sub.adoc | 1 - pom.xml | 21 +------------------ 4 files changed, 6 insertions(+), 28 deletions(-) delete mode 100644 jenkins-client/src/site/asciidoc/index.adoc delete mode 100644 jenkins-client/src/site/asciidoc/sub/sub.adoc diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 7847f3a9..71176ed3 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -2,6 +2,11 @@ ## Release 0.4.0 (NOT RELEASED YET) + * [Fixed Issue 465][issue-465] + + * Remove asciidoctor site parts + * AS preparation for user guide. + * [Fixed Issue 464][issue-464] * Replaced xml-apis with xerces-xmlParserAPI. diff --git a/jenkins-client/src/site/asciidoc/index.adoc b/jenkins-client/src/site/asciidoc/index.adoc deleted file mode 100644 index 942df55c..00000000 --- a/jenkins-client/src/site/asciidoc/index.adoc +++ /dev/null @@ -1,7 +0,0 @@ -:revnumber: ${project-version} - -== Overview == - -Here you can see the first page. -This is the first. - diff --git a/jenkins-client/src/site/asciidoc/sub/sub.adoc b/jenkins-client/src/site/asciidoc/sub/sub.adoc deleted file mode 100644 index 345e6aef..00000000 --- a/jenkins-client/src/site/asciidoc/sub/sub.adoc +++ /dev/null @@ -1 +0,0 @@ -Test diff --git a/pom.xml b/pom.xml index 25ea5774..d4eb4c74 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,7 @@ true true - 1.6.0 + 2.0.0 1.644 @@ -362,26 +362,7 @@ doxia-module-markdown 1.9 - - org.asciidoctor - asciidoctor-maven-plugin - ${asciidoctor-maven-plugin.version} - - - - - - font - coderay - style - 2 - ${project.version} - true - true - - - From 78a3e33de7f7c31f8e8f4013fc3b4c9824fc42dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Jun 2020 05:49:34 +0000 Subject: [PATCH 67/68] Bump dom4j from 2.1.1 to 2.1.3 Bumps [dom4j](https://github.com/dom4j/dom4j) from 2.1.1 to 2.1.3. - [Release notes](https://github.com/dom4j/dom4j/releases) - [Commits](https://github.com/dom4j/dom4j/compare/version-2.1.1...version-2.1.3) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d4eb4c74..f88539d9 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ org.dom4j dom4j - 2.1.1 + 2.1.3 From ddf6a850beacf79480280c0c3c067bf73d84bca5 Mon Sep 17 00:00:00 2001 From: Karl Heinz Marbaise Date: Sun, 20 Sep 2020 22:27:39 +0200 Subject: [PATCH 68/68] Add .sdkmanrc file. --- .sdkmanrc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .sdkmanrc diff --git a/.sdkmanrc b/.sdkmanrc new file mode 100644 index 00000000..4fc377de --- /dev/null +++ b/.sdkmanrc @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# Enable auto-env through the sdkman_auto_env config +# Add key=value pairs of SDKs to use below +java=8.0.252.hs-adpt