diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index f49a4e1..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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. \ No newline at end of file diff --git a/README.md b/README.md index 87f8957..e79032a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.cdancy/jenkins-rest/badge.png)](https://maven-badges.herokuapp.com/maven-central/io.github.cdancy/jenkins-rest) [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-jenkins–rest-4183C4.svg)](https://stackoverflow.com/questions/tagged/jenkins+rest) -# jenkins-rest +# jenkins-client-java Java client is built on the top of jclouds for working with Jenkins REST API. diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 7c026b6..966c538 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,6 @@ +### Version 2.0.0 (April 1, 2024) +* Fix to java 17 and change to use HttpClient with Spring + ### Version 1.0.2 (September 29, 2022) * ADDED: extensive build info. - [Pull Request 259](https://github.com/cdancy/jenkins-rest/pull/259) diff --git a/build.gradle b/build.gradle index 86dfe65..327a227 100644 --- a/build.gradle +++ b/build.gradle @@ -15,23 +15,20 @@ repositories { } dependencies { - ext.jcloudsVersion = '2.5.0' - ext.autoValueVersion = '1.10.4' - ext.autoServiceVersion = '1.1.1' - ext.guiceVersion = '5.1.0' + implementation 'org.jetbrains:annotations:24.0.0' + ext.autoValueVersion = '2.0.0' + ext.autoServiceVersion = '2.0.0' - implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359' - implementation 'javax.annotation:javax.annotation-api:1.3.2' - implementation ("org.apache.jclouds:jclouds-core:${jcloudsVersion}") - implementation ("com.google.inject:guice:${guiceVersion}") - implementation ("com.google.inject.extensions:guice-assistedinject:${guiceVersion}") - implementation ("com.google.auto.service:auto-service-annotations:${autoServiceVersion}") - annotationProcessor ("com.google.auto.service:auto-service:${autoServiceVersion}") - implementation ("com.google.auto.value:auto-value-annotations:${autoValueVersion}") - annotationProcessor ("com.google.auto.value:auto-value:${autoValueVersion}") + implementation group: 'org.springframework', name: 'spring-context', version: '6.1.5' + implementation group: 'org.springframework', name: 'spring-webflux', version: '6.1.5' + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.17.0' + + compileOnly 'org.projectlombok:lombok:1.18.32' + annotationProcessor 'org.projectlombok:lombok:1.18.32' + + testCompileOnly 'org.projectlombok:lombok:1.18.32' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.32' - testImplementation ("org.apache.jclouds:jclouds-core:${jcloudsVersion}:tests") - testImplementation ("org.apache.jclouds.driver:jclouds-slf4j:${jcloudsVersion}") testImplementation ('org.assertj:assertj-core:3.25.1') testImplementation ('ch.qos.logback:logback-core:1.4.14') testImplementation ('com.squareup.okhttp3:mockwebserver:4.12.0') @@ -39,7 +36,7 @@ dependencies { testImplementation ('ch.qos.logback:logback-classic:1.4.14') } -ext.compatibilityVersion = JavaVersion.VERSION_11 +ext.compatibilityVersion = JavaVersion.VERSION_17 ext.javadocPath = compatibilityVersion.isJava8() ? '' : 'en/java/' sourceCompatibility = compatibilityVersion targetCompatibility = compatibilityVersion @@ -106,7 +103,6 @@ javadoc { source = sourceSets.main.allJava options.with { links "https://docs.oracle.com/${javadocPath}javase/${compatibilityVersion.toString().replaceAll(/.*\./,"")}/docs/api" - links "https://google.github.io/guice/api-docs/${dependencies.guiceVersion}/javadoc/" addStringOption('Xdoclint:none', '-quiet') addStringOption('source', compatibilityVersion.toString().replaceAll(/.*\./,"")) } diff --git a/gradle.properties b/gradle.properties index ee02f42..e03e5a6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -group = io.github.cdancy +group = io.github.hillelmed version = 1.0.2 artifactoryURL = http://127.0.0.1:8080/artifactory diff --git a/settings.gradle b/settings.gradle index 408e43b..1a61361 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,4 +5,4 @@ pluginManagement { } } -rootProject.name = "jenkins-rest" +rootProject.name = "jenkins-client-java" diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile index b1f79fe..93f8937 100644 --- a/src/main/docker/Dockerfile +++ b/src/main/docker/Dockerfile @@ -1,4 +1,4 @@ -ARG jenkins_tag=2.401.3-lts-jdk17 +ARG jenkins_tag=2.440.2-jdk17 FROM jenkins/jenkins:$jenkins_tag COPY --chown=jenkins:jenkins init.groovy.d/ /usr/share/jenkins/ref/init.groovy.d/ diff --git a/src/main/java/com/cdancy/jenkins/rest/JenkinsApiMetadata.java b/src/main/java/com/cdancy/jenkins/rest/JenkinsApiMetadata.java deleted file mode 100644 index 52c10c4..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/JenkinsApiMetadata.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest; - -import java.net.URI; -import java.util.Properties; - -import org.jclouds.apis.ApiMetadata; -import org.jclouds.rest.internal.BaseHttpApiMetadata; - -import com.cdancy.jenkins.rest.config.JenkinsHttpApiModule; -import com.google.auto.service.AutoService; -import com.google.common.collect.ImmutableSet; -import com.google.inject.Module; - -@AutoService(ApiMetadata.class) -public class JenkinsApiMetadata extends BaseHttpApiMetadata { - - public static final String API_VERSION = "1.0"; - public static final String BUILD_VERSION = "2.0"; - - @Override - public Builder toBuilder() { - return new Builder().fromApiMetadata(this); - } - - public JenkinsApiMetadata() { - this(new Builder()); - } - - protected JenkinsApiMetadata(Builder builder) { - super(builder); - } - - public static Properties defaultProperties() { - return BaseHttpApiMetadata.defaultProperties(); - } - - public static class Builder extends BaseHttpApiMetadata.Builder { - - protected Builder() { - super(JenkinsApi.class); - id("jenkins").name("Jenkins API").identityName("Optional Username").credentialName("Optional Password") - .defaultIdentity("").defaultCredential("") - .documentation(URI.create("http://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API")) - .version(API_VERSION).buildVersion(BUILD_VERSION).defaultEndpoint("http://127.0.0.1:8080") - .defaultProperties(JenkinsApiMetadata.defaultProperties()) - .defaultModules(ImmutableSet.of(JenkinsHttpApiModule.class)); - } - - @Override - public JenkinsApiMetadata build() { - return new JenkinsApiMetadata(this); - } - - @Override - protected Builder self() { - return this; - } - - @Override - public Builder fromApiMetadata(ApiMetadata in) { - return this; - } - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/JenkinsClient.java b/src/main/java/com/cdancy/jenkins/rest/JenkinsClient.java deleted file mode 100644 index bae330e..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/JenkinsClient.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest; - -import com.cdancy.jenkins.rest.auth.AuthenticationType; -import com.cdancy.jenkins.rest.config.JenkinsAuthenticationModule; -import com.google.common.collect.Lists; -import com.google.inject.Module; - -import java.io.Closeable; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Properties; - -import org.jclouds.ContextBuilder; -import org.jclouds.javax.annotation.Nullable; - -public final class JenkinsClient implements Closeable { - - private final String endPoint; - private final JenkinsAuthentication credentials; - private final JenkinsApi jenkinsApi; - private final Properties overrides; - - /** - * Create a JenkinsClient inferring endpoint and authentication from - * environment and system properties. - */ - public JenkinsClient() { - this(null, null, null, null); - } - - /** - * Create an JenkinsClient. If any of the passed in variables are null we - * will query System Properties and Environment Variables, in order, to - * search for values that may be set in a devops/CI fashion. The only - * difference is the `overrides` which gets merged, but takes precedence, - * with those System Properties and Environment Variables found. - * - * @param endPoint URL of Jenkins instance. - * @param authentication authentication used to connect to Jenkins instance. - * @param overrides jclouds Properties to override defaults when creating a new JenkinsApi. - * @param modules a list of modules to be passed to the Contextbuilder, e.g. for logging. - */ - public JenkinsClient(@Nullable final String endPoint, - @Nullable final JenkinsAuthentication authentication, - @Nullable final Properties overrides, - @Nullable final List modules) { - this.endPoint = endPoint != null - ? endPoint - : JenkinsUtils.inferEndpoint(); - this.credentials = authentication != null - ? authentication - : JenkinsUtils.inferAuthentication(); - this.overrides = mergeOverrides(overrides); - this.jenkinsApi = createApi(this.endPoint, this.credentials, this.overrides, modules); - } - - private JenkinsApi createApi(final String endPoint, final JenkinsAuthentication authentication, final Properties overrides, final List modules) { - final List allModules = Lists.newArrayList(new JenkinsAuthenticationModule(authentication)); - if (modules != null) { - allModules.addAll(modules); - } - return ContextBuilder - .newBuilder(new JenkinsApiMetadata.Builder().build()) - .endpoint(endPoint) - .modules(allModules) - .overrides(overrides) - .buildApi(JenkinsApi.class); - } - - /** - * Query System Properties and Environment Variables for overrides and merge - * the potentially passed in overrides with those. - * - * @param possibleOverrides Optional passed in overrides. - * @return Properties object. - */ - private Properties mergeOverrides(final Properties possibleOverrides) { - final Properties inferOverrides = JenkinsUtils.inferOverrides(); - if (possibleOverrides != null) { - inferOverrides.putAll(possibleOverrides); - } - return inferOverrides; - } - - public String endPoint() { - return this.endPoint; - } - - @Deprecated - public String credentials() { - return this.authValue(); - } - - public Properties overrides() { - return this.overrides; - } - - public String authValue() { - return this.credentials.authValue(); - } - - public AuthenticationType authType() { - return this.credentials.authType(); - } - - public JenkinsApi api() { - return this.jenkinsApi; - } - - public static Builder builder() { - return new Builder(); - } - - @Override - public void close() throws IOException { - if (this.api() != null) { - this.api().close(); - } - } - - public static class Builder { - - private String endPoint; - private JenkinsAuthentication.Builder authBuilder; - private Properties overrides; - private List modules = Lists.newArrayList(); - - /** - * Define the base endpoint to connect to. - * - * @param endPoint Jenkins base endpoint. - * @return this Builder. - */ - public Builder endPoint(final String endPoint) { - this.endPoint = endPoint; - return this; - } - - /** - * Optional credentials to use for authentication. Must take the form of - * `username:password` or its base64 encoded version. - * - * @param optionallyBase64EncodedCredentials authentication credentials. - * @return this Builder. - */ - public Builder credentials(final String optionallyBase64EncodedCredentials) { - authBuilder = JenkinsAuthentication.builder() - .credentials(optionallyBase64EncodedCredentials); - return this; - } - - /** - * Optional Api token to use for authentication. - * This is not a Bearer token, hence the name apiToken. - * - * @param apiToken authentication token. - * @return this Builder. - */ - public Builder apiToken(final String apiToken) { - authBuilder = JenkinsAuthentication.builder() - .apiToken(apiToken); - return this; - } - - /** - * Optional jclouds Properties to override. What can be overridden can - * be found here: - * - *

https://github.com/jclouds/jclouds/blob/master/core/src/main/java/org/jclouds/Constants.java - * - * @param overrides optional jclouds Properties to override. - * @return this Builder. - */ - public Builder overrides(final Properties overrides) { - this.overrides = overrides; - return this; - } - - /** - * Optional List of Module to add. Modules can be added, for logging - * for example. - * - * @param modules optional List of Module to add. - * @return this Builder. - */ - public Builder modules(final Module... modules) { - this.modules.addAll(Arrays.asList(modules)); - return this; - } - - /** - * Build an instance of JenkinsClient. - * - * @return JenkinsClient - */ - public JenkinsClient build() { - - // 1.) If user passed in some auth use/build that. - final JenkinsAuthentication authentication = authBuilder != null - ? authBuilder.build() - : null; - - return new JenkinsClient(endPoint, authentication, overrides, modules); - } - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/binders/BindMapToForm.java b/src/main/java/com/cdancy/jenkins/rest/binders/BindMapToForm.java deleted file mode 100644 index ea8eccc..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/binders/BindMapToForm.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.binders; - -import static com.google.common.base.Preconditions.checkArgument; - -import java.util.List; -import java.util.Map; - -import javax.inject.Singleton; - -import com.google.common.collect.Lists; -import org.jclouds.http.HttpRequest; -import org.jclouds.http.HttpRequest.Builder; -import org.jclouds.rest.Binder; - -@Singleton -public class BindMapToForm implements Binder { - @SuppressWarnings("unchecked") - @Override - public R bindToRequest(final R request, final Object properties) { - - if (properties == null) { - return (R) request.toBuilder().build(); - } - - checkArgument(properties instanceof Map, "binder is only valid for Map"); - Map> props = (Map>) properties; - - Builder builder = request.toBuilder(); - for (Map.Entry> prop : props.entrySet()) { - if (prop.getKey() != null) { - String potentialKey = prop.getKey().trim(); - if (potentialKey.length() > 0) { - if (prop.getValue() == null) { - prop.setValue(Lists.newArrayList("")); - } - - builder.addFormParam(potentialKey, prop.getValue().toArray(new String[prop.getValue().size()])); - } - } - } - - return (R) builder.build(); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/config/JenkinsAuthenticationModule.java b/src/main/java/com/cdancy/jenkins/rest/config/JenkinsAuthenticationModule.java deleted file mode 100644 index a7f1d44..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/config/JenkinsAuthenticationModule.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.config; - -import com.cdancy.jenkins.rest.JenkinsAuthentication; -import com.google.inject.AbstractModule; -import java.util.Objects; - -/** - * Configure the provider for JenkinsAuthentication. - */ -public class JenkinsAuthenticationModule extends AbstractModule { - - private final JenkinsAuthentication authentication; - - public JenkinsAuthenticationModule(final JenkinsAuthentication authentication) { - this.authentication = Objects.requireNonNull(authentication); - } - - @Override - protected void configure() { - bind(JenkinsAuthentication.class).toProvider(new JenkinsAuthenticationProvider(authentication)); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/config/JenkinsAuthenticationProvider.java b/src/main/java/com/cdancy/jenkins/rest/config/JenkinsAuthenticationProvider.java deleted file mode 100644 index 6354ca8..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/config/JenkinsAuthenticationProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.config; - -import com.cdancy.jenkins.rest.JenkinsAuthentication; -import com.google.inject.Inject; -import com.google.inject.Provider; - -/** - * Provider for JenkinsAuthentication objects. The JenkinsAuthentication - * should be created ahead of time with this module simply handing it out - * to downstream objects for injection. - */ -public class JenkinsAuthenticationProvider implements Provider { - - private final JenkinsAuthentication creds; - - @Inject - public JenkinsAuthenticationProvider(final JenkinsAuthentication creds) { - this.creds = creds; - } - - @Override - public JenkinsAuthentication get() { - return creds; - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/config/JenkinsHttpApiModule.java b/src/main/java/com/cdancy/jenkins/rest/config/JenkinsHttpApiModule.java deleted file mode 100644 index 045e2c9..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/config/JenkinsHttpApiModule.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.config; - -import org.jclouds.http.HttpErrorHandler; -import org.jclouds.http.annotation.ClientError; -import org.jclouds.http.annotation.Redirection; -import org.jclouds.http.annotation.ServerError; -import org.jclouds.rest.ConfiguresHttpApi; -import org.jclouds.rest.config.HttpApiModule; - -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.handlers.JenkinsErrorHandler; - -@ConfiguresHttpApi -public class JenkinsHttpApiModule extends HttpApiModule { - - @Override - protected void bindErrorHandlers() { - bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(JenkinsErrorHandler.class); - bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(JenkinsErrorHandler.class); - bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(JenkinsErrorHandler.class); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/common/RequestStatus.java b/src/main/java/com/cdancy/jenkins/rest/domain/common/RequestStatus.java deleted file mode 100644 index b9619bc..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/common/RequestStatus.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.common; - -import java.util.List; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.cdancy.jenkins.rest.JenkinsUtils; -import com.google.auto.value.AutoValue; - -/** - * Generic response to be returned when an endpoint returns - * no content (i.e. 204 response code). - * - *

When the response code is valid the `value` parameter will - * be set to true while a non-valid response has the `value` set to - * false along with any potential `error` objects returned from Jenkins. - */ -@AutoValue -public abstract class RequestStatus implements Value, ErrorsHolder { - - @SerializedNames({ "value", "errors" }) - public static RequestStatus create(@Nullable final Boolean value, - final List errors) { - - return new AutoValue_RequestStatus(value, - JenkinsUtils.nullToEmpty(errors)); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/crumb/Crumb.java b/src/main/java/com/cdancy/jenkins/rest/domain/crumb/Crumb.java deleted file mode 100644 index b0125e7..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/crumb/Crumb.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.crumb; - -import java.util.List; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.cdancy.jenkins.rest.domain.common.Error; -import com.cdancy.jenkins.rest.domain.common.ErrorsHolder; -import com.cdancy.jenkins.rest.JenkinsUtils; -import com.google.auto.value.AutoValue; - -@AutoValue -public abstract class Crumb implements ErrorsHolder { - - @Nullable - public abstract String value(); - - @Nullable - public abstract String sessionIdCookie(); - - @SerializedNames({ "value", "errors" }) - public static Crumb create(final String value, - final List errors) { - - return create(value, null, errors); - } - - @SerializedNames({ "value", "sessionIdCookie" }) - public static Crumb create(final String value, final String sessionIdCookie) { - return create(value, sessionIdCookie, null); - } - - private static Crumb create(final String value, final String sessionIdCookie, - final List errors) { - - return new AutoValue_Crumb(JenkinsUtils.nullToEmpty(errors), value, - sessionIdCookie); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/Action.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/Action.java deleted file mode 100644 index 8f709a6..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/Action.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.job; - -import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableList; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import java.util.List; - -@AutoValue -public abstract class Action { - - public abstract List causes(); - - public abstract List parameters(); - - @Nullable - public abstract String text(); - - @Nullable - public abstract String iconPath(); - - @Nullable - public abstract String _class(); - Action() { - } - - @SerializedNames({"causes", "parameters", "text", "iconPath", "_class"}) - public static Action create(final List causes, final List parameters, final String text, final String iconPath, final String _class) { - return new AutoValue_Action( - causes != null ? ImmutableList.copyOf(causes) : ImmutableList.of(), - parameters != null ? ImmutableList.copyOf(parameters) : ImmutableList.of(), - text, iconPath, _class - ); - } -} - diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/BuildInfo.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/BuildInfo.java deleted file mode 100644 index 998a08b..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/BuildInfo.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.job; - -import java.util.List; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableList; - -@AutoValue -public abstract class BuildInfo { - - public abstract List artifacts(); - - public abstract List actions(); - - public abstract boolean building(); - - @Nullable - public abstract String description(); - - @Nullable - public abstract String displayName(); - - public abstract long duration(); - - public abstract long estimatedDuration(); - - @Nullable - public abstract String fullDisplayName(); - - @Nullable - public abstract String id(); - - public abstract boolean keepLog(); - - public abstract int number(); - - public abstract int queueId(); - - @Nullable - public abstract String result(); - - public abstract long timestamp(); - - @Nullable - public abstract String url(); - - public abstract List changeSets(); - - @Nullable - public abstract String builtOn(); - - public abstract List culprits(); - - BuildInfo() { - } - - @SerializedNames({ "artifacts", "actions", "building", "description", "displayName", "duration", "estimatedDuration", - "fullDisplayName", "id", "keepLog", "number", "queueId", "result", "timestamp", "url", "changeSets", "builtOn", "culprits" }) - public static BuildInfo create(List artifacts, List actions, boolean building, String description, String displayName, - long duration, long estimatedDuration, String fullDisplayName, String id, boolean keepLog, int number, - int queueId, String result, long timestamp, String url, List changeSets, String builtOn, List culprits) { - return new AutoValue_BuildInfo( - artifacts != null ? ImmutableList.copyOf(artifacts) : ImmutableList. of(), - actions != null ? ImmutableList.copyOf(actions) : ImmutableList. of(), - building, description, displayName, duration, estimatedDuration, fullDisplayName, - id, keepLog, number, queueId, result, timestamp, url, - changeSets != null ? ImmutableList.copyOf(changeSets) : ImmutableList. of(), - builtOn, - culprits != null ? ImmutableList.copyOf(culprits) : ImmutableList. of()); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/ChangeSet.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/ChangeSet.java deleted file mode 100644 index ebe103a..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/ChangeSet.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.job; - -import java.util.List; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableList; - -@AutoValue -public abstract class ChangeSet { - - public abstract List affectedPaths(); - - public abstract String commitId(); - - public abstract long timestamp(); - - public abstract Culprit author(); - - @Nullable - public abstract String authorEmail(); - - @Nullable - public abstract String comment(); - - ChangeSet() { - } - - @SerializedNames({ "affectedPaths", "commitId", "timestamp", "author", "authorEmail", "comment" }) - public static ChangeSet create(List affectedPaths, String commitId, long timestamp, Culprit author, String authorEmail, String comment) { - return new AutoValue_ChangeSet( - affectedPaths != null ? ImmutableList.copyOf(affectedPaths) : ImmutableList. of(), - commitId, timestamp, author, authorEmail, comment); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/ChangeSetList.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/ChangeSetList.java deleted file mode 100644 index 89a61c5..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/ChangeSetList.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.job; - -import java.util.List; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableList; - -@AutoValue -public abstract class ChangeSetList { - - public abstract List items(); - - @Nullable - public abstract String kind(); - - ChangeSetList() { - } - - @SerializedNames({ "items", "kind" }) - public static ChangeSetList create(List items, String kind) { - return new AutoValue_ChangeSetList( - items != null ? ImmutableList.copyOf(items) : ImmutableList. of(), - kind); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/Job.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/Job.java deleted file mode 100644 index 090b4a1..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/Job.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.cdancy.jenkins.rest.domain.job; - -import com.google.auto.value.AutoValue; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class Job { - - @Nullable - public abstract String clazz(); - - public abstract String name(); - - public abstract String url(); - - @Nullable - public abstract String color(); - - Job() { - } - - @SerializedNames({"_class", "name", "url", "color"}) - public static Job create(final String clazz, final String name, final String url, final String color) { - return new AutoValue_Job(clazz, name, url, color); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/JobInfo.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/JobInfo.java deleted file mode 100644 index 3a3454f..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/JobInfo.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.job; - -import java.util.List; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.cdancy.jenkins.rest.domain.queue.QueueItem; -import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableList; - -@AutoValue -public abstract class JobInfo { - - @Nullable - public abstract String description(); - - @Nullable - public abstract String displayName(); - - @Nullable - public abstract String displayNameOrNull(); - - public abstract String name(); - - public abstract String url(); - - public abstract boolean buildable(); - - public abstract List builds(); - - @Nullable - public abstract String color(); - - @Nullable - public abstract BuildInfo firstBuild(); - - public abstract boolean inQueue(); - - public abstract boolean keepDependencies(); - - @Nullable - public abstract BuildInfo lastBuild(); - - @Nullable - public abstract BuildInfo lastCompleteBuild(); - - @Nullable - public abstract BuildInfo lastFailedBuild(); - - @Nullable - public abstract BuildInfo lastStableBuild(); - - @Nullable - public abstract BuildInfo lastSuccessfulBuild(); - - @Nullable - public abstract BuildInfo lastUnstableBuild(); - - @Nullable - public abstract BuildInfo lastUnsuccessfulBuild(); - - public abstract int nextBuildNumber(); - - @Nullable - public abstract QueueItem queueItem(); - - public abstract boolean concurrentBuild(); - - JobInfo() { - } - - @SerializedNames({ "description", "displayName", "displayNameOrNull", "name", "url", "buildable", "builds", "color", - "firstBuild", "inQueue", "keepDependencies", "lastBuild", "lastCompleteBuild", "lastFailedBuild", - "lastStableBuild", "lastSuccessfulBuild", "lastUnstableBuild", "lastUnsuccessfulBuild", "nextBuildNumber", - "queueItem", "concurrentBuild" }) - public static JobInfo create(String description, String displayName, String displayNameOrNull, String name, - String url, boolean buildable, List builds, String color, BuildInfo firstBuild, boolean inQueue, - boolean keepDependencies, BuildInfo lastBuild, BuildInfo lastCompleteBuild, BuildInfo lastFailedBuild, - BuildInfo lastStableBuild, BuildInfo lastSuccessfulBuild, BuildInfo lastUnstableBuild, BuildInfo lastUnsuccessfulBuild, - int nextBuildNumber, QueueItem queueItem, boolean concurrentBuild) { - return new AutoValue_JobInfo(description, displayName, displayNameOrNull, name, url, buildable, - builds != null ? ImmutableList.copyOf(builds) : ImmutableList. of(), color, firstBuild, inQueue, - keepDependencies, lastBuild, lastCompleteBuild, lastFailedBuild, lastStableBuild, lastSuccessfulBuild, - lastUnstableBuild, lastUnsuccessfulBuild, nextBuildNumber, queueItem, concurrentBuild); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/PipelineNode.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/PipelineNode.java deleted file mode 100644 index 26d3913..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/PipelineNode.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.cdancy.jenkins.rest.domain.job; - -import java.util.List; - -import com.google.auto.value.AutoValue; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class PipelineNode { - - public abstract String name(); - - public abstract String status(); - - public abstract long startTimeMillis(); - - public abstract long durationTimeMillis(); - - public abstract List stageFlowNodes(); - - PipelineNode() { - } - - @SerializedNames({ "name", "status", "startTimeMillis", "durationTimeMillis", "stageFlowNodes" }) - public static PipelineNode create(String name, String status, long startTimeMillis, long durationTimeMillis, List stageFlowNodes) { - return new AutoValue_PipelineNode(name, status, startTimeMillis, durationTimeMillis, stageFlowNodes); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/PipelineNodeLog.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/PipelineNodeLog.java deleted file mode 100644 index 51e6cbc..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/PipelineNodeLog.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.cdancy.jenkins.rest.domain.job; - -import com.google.auto.value.AutoValue; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class PipelineNodeLog { - - public abstract String nodeId(); - - public abstract String nodeStatus(); - - public abstract int length(); - - public abstract boolean hasMore(); - - public abstract String text(); - - public abstract String consoleUrl(); - - PipelineNodeLog() { - } - - @SerializedNames({ "nodeId", "nodeStatus", "length", "hasMore", "text", "consoleUrl" }) - public static PipelineNodeLog create(String nodeId, String nodeStatus, int length, boolean hasMore, String text, String consoleUrl) { - return new AutoValue_PipelineNodeLog(nodeId, nodeStatus, length, hasMore, text, consoleUrl); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/Stage.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/Stage.java deleted file mode 100644 index 8b7d73c..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/Stage.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.job; - -import com.google.auto.value.AutoValue; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class Stage { - public abstract String id(); - - public abstract String name(); - - public abstract String status(); - - public abstract long startTimeMillis(); - - public abstract long endTimeMillis(); - - public abstract long pauseDurationMillis(); - - public abstract long durationMillis(); - - Stage() { - } - - @SerializedNames({ "id", "name", "status", "startTimeMillis", "endTimeMillis", "pauseDurationMillis", "durationMillis" }) - public static Stage create(String id, String name, String status, long startTimeMillis, long endTimeMillis, long pauseDurationMillis, long durationMillis) { - return new AutoValue_Stage(id, name, status, startTimeMillis, endTimeMillis, pauseDurationMillis, durationMillis); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/StageFlowNode.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/StageFlowNode.java deleted file mode 100644 index 564445c..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/StageFlowNode.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.job; - -import java.util.List; - -import com.google.auto.value.AutoValue; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class StageFlowNode { - - public abstract String name(); - - public abstract String status(); - - public abstract long startTimeMillis(); - - public abstract long durationTimeMillis(); - - public abstract List parentNodes(); - - StageFlowNode() { - } - - @SerializedNames({ "name", "status", "startTimeMillis", "durationTimeMillis", "parentNodes" }) - public static StageFlowNode create(String name, String status, long startTimeMillis, long durationTimeMillis, List parentNodes) { - return new AutoValue_StageFlowNode(name, status, startTimeMillis, durationTimeMillis, parentNodes); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/Workflow.java b/src/main/java/com/cdancy/jenkins/rest/domain/job/Workflow.java deleted file mode 100644 index c056564..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/Workflow.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.job; - -import java.util.List; - -import com.google.auto.value.AutoValue; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class Workflow { - - public abstract String name(); - - public abstract String status(); - - public abstract long startTimeMillis(); - - public abstract long durationTimeMillis(); - - public abstract List stages(); - - Workflow() { - } - - @SerializedNames({ "name", "status", "startTimeMillis", "durationTimeMillis", "stages" }) - public static Workflow create(String name, String status, long startTimeMillis, long durationTimeMillis, List stages) { - return new AutoValue_Workflow(name, status, startTimeMillis, durationTimeMillis, stages); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/plugins/Plugin.java b/src/main/java/com/cdancy/jenkins/rest/domain/plugins/Plugin.java deleted file mode 100644 index 404d29a..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/plugins/Plugin.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.plugins; - - -import org.jclouds.json.SerializedNames; - -import com.google.auto.value.AutoValue; -import org.jclouds.javax.annotation.Nullable; - -@AutoValue -public abstract class Plugin { - - @Nullable - public abstract Boolean active(); - - @Nullable - public abstract String backupVersion(); - - @Nullable - public abstract Boolean bundled(); - - @Nullable - public abstract Boolean deleted(); - - @Nullable - public abstract Boolean downgradable(); - - @Nullable - public abstract Boolean enabled(); - - @Nullable - public abstract Boolean hasUpdate(); - - @Nullable - public abstract String longName(); - - @Nullable - public abstract Boolean pinned(); - - @Nullable - public abstract String requiredCoreVersion(); - - @Nullable - public abstract String shortName(); - - @Nullable - public abstract String supportsDynamicLoad(); - - @Nullable - public abstract String url(); - - @Nullable - public abstract String version(); - - Plugin() { - } - - @SerializedNames({ "active", "backupVersion", "bundled", - "deleted", "downgradable", "enabled", - "hasUpdate", "longName", "pinned", - "requiredCoreVersion", "shortName", "supportsDynamicLoad", - "url", "version"}) - public static Plugin create(Boolean active, String backupVersion, Boolean bundled, - Boolean deleted, Boolean downgradable, Boolean enabled, - Boolean hasUpdate, String longName, Boolean pinned, - String requiredCoreVersion, String shortName, String supportsDynamicLoad, - String url, String version) { - return new AutoValue_Plugin(active, backupVersion, bundled, - deleted, downgradable, enabled, - hasUpdate, longName, pinned, - requiredCoreVersion, shortName, supportsDynamicLoad, - url, version); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/plugins/Plugins.java b/src/main/java/com/cdancy/jenkins/rest/domain/plugins/Plugins.java deleted file mode 100644 index ee0042d..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/plugins/Plugins.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.plugins; - -import com.cdancy.jenkins.rest.JenkinsUtils; -import com.cdancy.jenkins.rest.domain.common.ErrorsHolder; -import com.cdancy.jenkins.rest.domain.common.Error; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.google.auto.value.AutoValue; - -import java.util.List; - -@AutoValue -public abstract class Plugins implements ErrorsHolder { - - @Nullable - public abstract String clazz(); - - public abstract List plugins(); - - Plugins() { - } - - @SerializedNames({ "_class", "plugins", "errors" }) - public static Plugins create(final String clazz, - final List plugins, - final List errors) { - return new AutoValue_Plugins(JenkinsUtils.nullToEmpty(errors), - clazz, - JenkinsUtils.nullToEmpty(plugins)); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/queue/QueueItem.java b/src/main/java/com/cdancy/jenkins/rest/domain/queue/QueueItem.java deleted file mode 100644 index f31a20d..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/queue/QueueItem.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.queue; - -import java.util.Map; - -import org.jclouds.json.SerializedNames; -import org.jclouds.javax.annotation.Nullable; - -import com.google.auto.value.AutoValue; -import com.google.common.collect.Maps; - -@AutoValue -public abstract class QueueItem { - - public abstract boolean blocked(); - - public abstract boolean buildable(); - - public abstract int id(); - - public abstract long inQueueSince(); - - public abstract Map params(); - - public abstract boolean stuck(); - - public abstract Task task(); - - public abstract String url(); - - @Nullable - public abstract String why(); - - // https://javadoc.jenkins.io/hudson/model/Queue.NotWaitingItem.html - /** - * When did this job exit the Queue.waitingList phase? - * For a Queue.NotWaitingItem - * @return The time expressed in milliseconds after January 1, 1970, 0:00:00 GMT. - */ - public abstract long buildableStartMilliseconds(); - - public abstract boolean cancelled(); - - @Nullable - public abstract Executable executable(); - - // https://javadoc.jenkins.io/hudson/model/Queue.WaitingItem.html - /** - * This item can be run after this time. - * For a Queue.WaitingItem - * @return The time expressed in milliseconds after January 1, 1970, 0:00:00 GMT. - */ - @Nullable - public abstract Long timestamp(); - - QueueItem() { - } - - @SerializedNames({ "blocked", "buildable", "id", "inQueueSince", "params", "stuck", "task", "url", "why", - "buildableStartMilliseconds", "cancelled", "executable", "timestamp"}) - public static QueueItem create(boolean blocked, boolean buildable, int id, long inQueueSince, String params, - boolean stuck, Task task, String url, String why, long buildableStartMilliseconds, - boolean cancelled, Executable executable, Long timestamp) { - Map parameters = Maps.newHashMap(); - if (params != null) { - params = params.trim(); - if (params.length() > 0) { - for (String keyValue : params.split("\n")) { - String[] pair = keyValue.split("="); - parameters.put(pair[0], pair.length > 1 ? pair[1] : ""); - } - } - } - return new AutoValue_QueueItem(blocked, buildable, id, inQueueSince, parameters, stuck, task, url, why, - buildableStartMilliseconds, cancelled, executable, timestamp); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/statistics/OverallLoad.java b/src/main/java/com/cdancy/jenkins/rest/domain/statistics/OverallLoad.java deleted file mode 100644 index e5f3e97..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/statistics/OverallLoad.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.statistics; - -import java.util.Map; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.google.auto.value.AutoValue; - -@AutoValue -public abstract class OverallLoad { - - @Nullable - public abstract Map availableExecutors(); - - @Nullable - public abstract Map busyExecutors(); - - @Nullable - public abstract Map connectingExecutors(); - - @Nullable - public abstract Map definedExecutors(); - - @Nullable - public abstract Map idleExecutors(); - - @Nullable - public abstract Map onlineExecutors(); - - @Nullable - public abstract Map queueLength(); - - @Nullable - public abstract Map totalExecutors(); - - @Nullable - public abstract Map totalQueueLength(); - - OverallLoad() { - } - - @SerializedNames({ "availableExecutors", "busyExecutors", "connectingExecutors", "definedExecutors", "idleExecutors", - "onlineExecutors", "queueLength", "totalExecutors", "totalQueueLength" }) - public static OverallLoad create(Map availableExecutors, Map busyExecutors, - Map connectingExecutors, Map definedExecutors, - Map idleExecutors, Map onlineExecutors, Map queueLength, - Map totalExecutors, Map totalQueueLength) { - return new AutoValue_OverallLoad(availableExecutors, busyExecutors, - connectingExecutors, definedExecutors, - idleExecutors, onlineExecutors, - queueLength, totalExecutors, - totalQueueLength); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/system/SystemInfo.java b/src/main/java/com/cdancy/jenkins/rest/domain/system/SystemInfo.java deleted file mode 100644 index 1db3c7d..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/system/SystemInfo.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.domain.system; - -import com.cdancy.jenkins.rest.JenkinsUtils; -import com.cdancy.jenkins.rest.domain.common.ErrorsHolder; -import com.cdancy.jenkins.rest.domain.common.Error; - -import org.jclouds.json.SerializedNames; -import org.jclouds.javax.annotation.Nullable; - -import com.google.auto.value.AutoValue; - -import java.util.List; - -@AutoValue -public abstract class SystemInfo implements ErrorsHolder { - - public abstract String hudsonVersion(); - - public abstract String jenkinsVersion(); - - public abstract String jenkinsSession(); - - public abstract String instanceIdentity(); - - @Nullable - public abstract String sshEndpoint(); - - public abstract String server(); - - SystemInfo() { - } - - @SerializedNames({ "hudsonVersion", "jenkinsVersion", "jenkinsSession", - "instanceIdentity", "sshEndpoint", "server", "errors" }) - public static SystemInfo create(String hudsonVersion, String jenkinsVersion, String jenkinsSession, - String instanceIdentity, - String sshEndpoint, String server, final List errors) { - return new AutoValue_SystemInfo(JenkinsUtils.nullToEmpty(errors), - hudsonVersion, jenkinsVersion, jenkinsSession, - instanceIdentity, sshEndpoint, server); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/user/ApiTokenData.java b/src/main/java/com/cdancy/jenkins/rest/domain/user/ApiTokenData.java deleted file mode 100644 index bb85d6f..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/user/ApiTokenData.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.domain.user; - -import com.google.auto.value.AutoValue; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class ApiTokenData { - - public abstract String tokenName(); - public abstract String tokenUuid(); - public abstract String tokenValue(); - - ApiTokenData() { - } - - @SerializedNames({"tokenName", "tokenUuid", "tokenValue"}) - public static ApiTokenData create(final String tokenName, final String tokenUuid, final String tokenValue) { - return new AutoValue_ApiTokenData(tokenName, tokenUuid, tokenValue); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/user/Property.java b/src/main/java/com/cdancy/jenkins/rest/domain/user/Property.java deleted file mode 100644 index 1c3e99a..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/user/Property.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.cdancy.jenkins.rest.domain.user; - -import com.google.auto.value.AutoValue; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class Property { - - public abstract String clazz(); - - Property() { - } - - @SerializedNames({"_class"}) - public static Property create(final String clazz) { - return new AutoValue_Property(clazz); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/user/User.java b/src/main/java/com/cdancy/jenkins/rest/domain/user/User.java deleted file mode 100644 index 153b724..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/domain/user/User.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.domain.user; - -import java.util.List; - -import com.google.auto.value.AutoValue; -import com.google.common.collect.ImmutableList; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -@AutoValue -public abstract class User { - - public abstract String absoluteUrl(); - - @Nullable - public abstract String description(); - - public abstract String fullName(); - - public abstract String id(); - - // TODO: Find a way to support properties, which is a list of different extensions of a base class - // public abstract List properties(); - - User() { - } - - @SerializedNames({"absoluteUrl", "description", "fullName", "id"}) - public static User create(final String absoluteUrl, final String description, final String fullName, final String id) { - return new AutoValue_User(absoluteUrl, description, fullName, id); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/fallbacks/JenkinsFallbacks.java b/src/main/java/com/cdancy/jenkins/rest/fallbacks/JenkinsFallbacks.java deleted file mode 100644 index c154a10..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/fallbacks/JenkinsFallbacks.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.fallbacks; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Predicates.equalTo; -import static com.google.common.base.Throwables.propagate; - -import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull; - -import com.cdancy.jenkins.rest.domain.common.IntegerResponse; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.common.Error; -import com.cdancy.jenkins.rest.domain.crumb.Crumb; -import com.cdancy.jenkins.rest.domain.plugins.Plugins; -import com.cdancy.jenkins.rest.domain.system.SystemInfo; - -import com.google.common.collect.Lists; -import com.google.gson.JsonSyntaxException; - -import java.util.List; - -import org.jclouds.Fallback; -import org.jclouds.rest.ResourceNotFoundException; - -public final class JenkinsFallbacks { - - public static final class SystemInfoOnError implements Fallback { - @Override - public Object createOrPropagate(final Throwable throwable) { - checkNotNull(throwable, "throwable"); - return createSystemInfoFromErrors(getErrors(throwable)); - } - } - - public static final class RequestStatusOnError implements Fallback { - @Override - public Object createOrPropagate(final Throwable throwable) { - checkNotNull(throwable, "throwable"); - try { - return RequestStatus.create(false, getErrors(throwable)); - } catch (JsonSyntaxException e) { - return RequestStatus.create(false, getErrors(e)); - } - } - } - - public static final class IntegerResponseOnError implements Fallback { - @Override - public Object createOrPropagate(final Throwable throwable) { - checkNotNull(throwable, "throwable"); - try { - return IntegerResponse.create(null, getErrors(throwable)); - } catch (JsonSyntaxException e) { - return IntegerResponse.create(null, getErrors(e)); - } - } - } - - public static final class CrumbOnError implements Fallback { - @Override - public Object createOrPropagate(final Throwable throwable) { - checkNotNull(throwable, "throwable"); - try { - return Crumb.create(null, getErrors(throwable)); - } catch (JsonSyntaxException e) { - return Crumb.create(null, getErrors(e)); - } - } - } - - public static final class PluginsOnError implements Fallback { - @Override - public Object createOrPropagate(final Throwable throwable) { - checkNotNull(throwable, "throwable"); - try { - return Plugins.create(null, null, getErrors(throwable)); - } catch (JsonSyntaxException e) { - return Plugins.create(null, null, getErrors(e)); - } - } - } - - // fix/hack for Jenkins jira issue: JENKINS-21311 - public static final class JENKINS_21311 implements Fallback { - @Override - public Object createOrPropagate(final Throwable throwable) { - checkNotNull(throwable, "throwable"); - try { - if (throwable.getClass() == ResourceNotFoundException.class) { - return RequestStatus.create(true, null); - } else { - return RequestStatus.create(false, getErrors(throwable)); - } - } catch (JsonSyntaxException e) { - return RequestStatus.create(false, getErrors(e)); - } - } - } - - public static SystemInfo createSystemInfoFromErrors(final List errors) { - final String illegalValue = "-1"; - return SystemInfo.create(illegalValue, illegalValue, illegalValue, - illegalValue, illegalValue, illegalValue, errors); - } - - /** - * Parse list of Error's from generic Exception. - * - * @param output Exception containing error data - * @return List of culled Error's - */ - public static List getErrors(final Exception output) { - final Error error = Error.create(null, output.getMessage(), - output.getClass().getName()); - return Lists.newArrayList(error); - } - - /** - * Parse list of Error's from output. - * - * @param output Throwable containing error data - * @return List of culled Error's - */ - public static List getErrors(final Throwable output) { - - final List errors = Lists.newArrayList(); - - String context = null; - String message = output.getMessage(); - final String [] messageParts = output.getMessage().split("->"); - switch (messageParts.length) { - case 1: message = messageParts[0].trim(); break; - case 3: context = messageParts[0].trim(); message = messageParts[2].trim(); break; - } - - final Error error = Error.create(context, message, output.getClass().getCanonicalName()); - errors.add(error); - - return errors; - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApi.java b/src/main/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApi.java deleted file mode 100644 index f1a679e..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApi.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.features; - -import javax.inject.Named; -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.parsers.RequestStatusParser; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.Payload; -import org.jclouds.rest.annotations.PayloadParam; - -import com.cdancy.jenkins.rest.fallbacks.JenkinsFallbacks; -import com.cdancy.jenkins.rest.filters.JenkinsAuthenticationFilter; - -@RequestFilters(JenkinsAuthenticationFilter.class) -@Path("/configuration-as-code") -public interface ConfigurationAsCodeApi { - - @Named("casc:check") - @Path("/check") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Payload("{cascYml}") - @POST - RequestStatus check(@PayloadParam(value = "cascYml") String cascYml); - - @Named("casc:apply") - @Path("/apply") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Payload("{cascYml}") - @POST - RequestStatus apply(@PayloadParam(value = "cascYml") String cascYml); -} diff --git a/src/main/java/com/cdancy/jenkins/rest/features/CrumbIssuerApi.java b/src/main/java/com/cdancy/jenkins/rest/features/CrumbIssuerApi.java deleted file mode 100644 index 1e90b46..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/features/CrumbIssuerApi.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.features; - -import javax.inject.Named; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.core.MediaType; - -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.QueryParams; - -import com.cdancy.jenkins.rest.domain.crumb.Crumb; -import com.cdancy.jenkins.rest.fallbacks.JenkinsFallbacks; -import com.cdancy.jenkins.rest.filters.JenkinsNoCrumbAuthenticationFilter; -import com.cdancy.jenkins.rest.parsers.CrumbParser; - -@RequestFilters(JenkinsNoCrumbAuthenticationFilter.class) -@Path("/crumbIssuer/api/xml") -public interface CrumbIssuerApi { - - @Named("crumb-issuer:crumb") - @Fallback(JenkinsFallbacks.CrumbOnError.class) - @ResponseParser(CrumbParser.class) - @QueryParams(keys = { "xpath" }, values = { "concat(//crumbRequestField,\":\",//crumb)" }) - @Consumes(MediaType.TEXT_PLAIN) - @GET - Crumb crumb(); -} diff --git a/src/main/java/com/cdancy/jenkins/rest/features/JobsApi.java b/src/main/java/com/cdancy/jenkins/rest/features/JobsApi.java deleted file mode 100644 index b1f9149..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/features/JobsApi.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.features; - -import java.io.InputStream; -import com.google.gson.JsonObject; -import java.util.List; -import java.util.Map; - -import javax.inject.Named; -import javax.ws.rs.Consumes; -import javax.ws.rs.FormParam; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; - -import com.cdancy.jenkins.rest.domain.job.*; -import com.cdancy.jenkins.rest.parsers.*; -import org.jclouds.Fallbacks; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.ParamParser; -import org.jclouds.rest.annotations.Payload; -import org.jclouds.rest.annotations.PayloadParam; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; - -import com.cdancy.jenkins.rest.binders.BindMapToForm; -import com.cdancy.jenkins.rest.domain.common.IntegerResponse; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.fallbacks.JenkinsFallbacks; -import com.cdancy.jenkins.rest.filters.JenkinsAuthenticationFilter; - -@RequestFilters(JenkinsAuthenticationFilter.class) -@Path("/") -public interface JobsApi { - - @Named("jobs:get-jobs") - @Path("{folderPath}api/json") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - JobList jobList(@PathParam("folderPath") @ParamParser(FolderPathParser.class) String folderPath); - - @Named("jobs:job-info") - @Path("{optionalFolderPath}job/{name}/api/json") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - JobInfo jobInfo(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:artifact") - @Path("{optionalFolderPath}job/{name}/{number}/api/json") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - BuildInfo buildInfo(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber); - - @Named("jobs:artifact") - @Path("{optionalFolderPath}job/{name}/{number}/artifact/{relativeArtifactPath}") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.WILDCARD) - @GET - InputStream artifact(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber, - @PathParam("relativeArtifactPath") String relativeArtifactPath); - - @Named("jobs:create") - @Path("{optionalFolderPath}createItem") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Produces(MediaType.APPLICATION_XML) - @Consumes(MediaType.WILDCARD) - @Payload("{configXML}") - @POST - RequestStatus create(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @QueryParam("name") String jobName, - @PayloadParam(value = "configXML") String configXML); - - @Named("jobs:get-config") - @Path("{optionalFolderPath}job/{name}/config.xml") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.TEXT_PLAIN) - @GET - String config(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:update-config") - @Path("{optionalFolderPath}job/{name}/config.xml") - @Fallback(Fallbacks.FalseOnNotFoundOr404.class) - @Produces(MediaType.APPLICATION_XML + ";charset=UTF-8") - @Consumes(MediaType.TEXT_HTML) - @Payload("{configXML}") - @POST - boolean config(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PayloadParam(value = "configXML") String configXML); - - @Named("jobs:get-description") - @Path("{optionalFolderPath}job/{name}/description") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.TEXT_PLAIN) - @GET - String description(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:set-description") - @Path("{optionalFolderPath}job/{name}/description") - @Fallback(Fallbacks.FalseOnNotFoundOr404.class) - @Consumes(MediaType.TEXT_HTML) - @POST - boolean description(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @FormParam("description") String description); - - @Named("jobs:delete") - @Path("{optionalFolderPath}job/{name}/doDelete") - @Consumes(MediaType.TEXT_HTML) - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @POST - RequestStatus delete(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:enable") - @Path("{optionalFolderPath}job/{name}/enable") - @Fallback(Fallbacks.FalseOnNotFoundOr404.class) - @Consumes(MediaType.TEXT_HTML) - @POST - boolean enable(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:disable") - @Path("{optionalFolderPath}job/{name}/disable") - @Fallback(Fallbacks.FalseOnNotFoundOr404.class) - @Consumes(MediaType.TEXT_HTML) - @POST - boolean disable(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:build") - @Path("{optionalFolderPath}job/{name}/build") - @Fallback(JenkinsFallbacks.IntegerResponseOnError.class) - @ResponseParser(LocationToQueueId.class) - @Consumes("application/unknown") - @POST - IntegerResponse build(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:stop-build") - @Path("{optionalFolderPath}job/{name}/{number}/stop") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Consumes(MediaType.APPLICATION_JSON) - @POST - RequestStatus stop(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber); - - @Named("jobs:term-build") - @Path("{optionalFolderPath}job/{name}/{number}/term") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Consumes(MediaType.APPLICATION_JSON) - @POST - RequestStatus term(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber); - - @Named("jobs:kill-build") - @Path("{optionalFolderPath}job/{name}/{number}/kill") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Consumes(MediaType.APPLICATION_JSON) - @POST - RequestStatus kill(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber); - - @Named("jobs:build-with-params") - @Path("{optionalFolderPath}job/{name}/buildWithParameters") - @Fallback(JenkinsFallbacks.IntegerResponseOnError.class) - @ResponseParser(LocationToQueueId.class) - @Consumes("application/unknown") - @POST - IntegerResponse buildWithParameters(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @Nullable @BinderParam(BindMapToForm.class) Map> properties); - - @Named("jobs:last-build-number") - @Path("{optionalFolderPath}job/{name}/lastBuild/buildNumber") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @ResponseParser(BuildNumberToInteger.class) - @Consumes(MediaType.TEXT_PLAIN) - @GET - Integer lastBuildNumber(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:last-build-timestamp") - @Path("{optionalFolderPath}job/{name}/lastBuild/buildTimestamp") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.TEXT_PLAIN) - @GET - String lastBuildTimestamp(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:progressive-text") - @Path("{optionalFolderPath}job/{name}/lastBuild/logText/progressiveText") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @ResponseParser(OutputToProgressiveText.class) - @Consumes(MediaType.TEXT_PLAIN) - @GET - ProgressiveText progressiveText(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @QueryParam("start") int start); - - @Named("jobs:progressive-text") - @Path("{optionalFolderPath}job/{name}/{number}/logText/progressiveText") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @ResponseParser(OutputToProgressiveText.class) - @Consumes(MediaType.TEXT_PLAIN) - @GET - ProgressiveText progressiveText(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber, - @QueryParam("start") int start); - - @Named("jobs:rename") - @Path("{optionalFolderPath}job/{name}/doRename") - @Fallback(Fallbacks.FalseOnNotFoundOr404.class) - @Consumes(MediaType.TEXT_HTML) - @POST - boolean rename(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @QueryParam("newName") String newName); - - // below four apis are for "pipeline-stage-view-plugin", - // see https://github.com/jenkinsci/pipeline-stage-view-plugin/tree/master/rest-api - @Named("jobs:run-history") - @Path("{optionalFolderPath}job/{name}/wfapi/runs") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - List runHistory(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName); - - @Named("jobs:workflow") - @Path("{optionalFolderPath}job/{name}/{number}/wfapi/describe") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - Workflow workflow(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber); - - @Named("jobs:pipeline-node") - @Path("{optionalFolderPath}job/{name}/{number}/execution/node/{nodeId}/wfapi/describe") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - PipelineNode pipelineNode(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber, @PathParam("nodeId") int nodeId); - - @Named("jobs:pipeline-node-log") - @Path("{optionalFolderPath}job/{name}/{number}/execution/node/{nodeId}/wfapi/log") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - PipelineNodeLog pipelineNodeLog(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber, @PathParam("nodeId") int nodeId); - - @Named("jobs:testReport") - @Path("{optionalFolderPath}job/{name}/{number}/testReport/api/json") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - JsonObject testReport(@Nullable @PathParam("optionalFolderPath") @ParamParser(OptionalFolderPathParser.class) String optionalFolderPath, - @PathParam("name") String jobName, - @PathParam("number") int buildNumber); - -} diff --git a/src/main/java/com/cdancy/jenkins/rest/features/PluginManagerApi.java b/src/main/java/com/cdancy/jenkins/rest/features/PluginManagerApi.java deleted file mode 100644 index 91185fb..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/features/PluginManagerApi.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.features; - -import javax.inject.Named; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.QueryParam; -import javax.ws.rs.POST; -import javax.ws.rs.Produces; - -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.plugins.Plugins; -import com.cdancy.jenkins.rest.fallbacks.JenkinsFallbacks; -import com.cdancy.jenkins.rest.filters.JenkinsAuthenticationFilter; -import com.cdancy.jenkins.rest.parsers.RequestStatusParser; - -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.Payload; -import org.jclouds.rest.annotations.PayloadParam; -import org.jclouds.rest.annotations.ResponseParser; - -@RequestFilters(JenkinsAuthenticationFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -@Path("/pluginManager") -public interface PluginManagerApi { - - @Named("pluginManager:plugins") - @Path("/api/json") - @Fallback(JenkinsFallbacks.PluginsOnError.class) - @GET - Plugins plugins(@Nullable @QueryParam("depth") Integer depth, - @Nullable @QueryParam("tree") String tree); - - @Named("pluginManager:install-necessary-plugins") - @Path("/installNecessaryPlugins") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Produces(MediaType.APPLICATION_XML) - @Payload("") - @POST - RequestStatus installNecessaryPlugins(@PayloadParam(value = "pluginID") String pluginID); -} diff --git a/src/main/java/com/cdancy/jenkins/rest/features/SystemApi.java b/src/main/java/com/cdancy/jenkins/rest/features/SystemApi.java deleted file mode 100644 index 81685d7..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/features/SystemApi.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.features; - -import javax.inject.Named; -import javax.ws.rs.Consumes; -import javax.ws.rs.HEAD; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.core.MediaType; - -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.parsers.RequestStatusParser; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.Fallback; - -import com.cdancy.jenkins.rest.domain.system.SystemInfo; -import com.cdancy.jenkins.rest.fallbacks.JenkinsFallbacks; -import com.cdancy.jenkins.rest.filters.JenkinsAuthenticationFilter; -import com.cdancy.jenkins.rest.parsers.SystemInfoFromJenkinsHeaders; - -@RequestFilters(JenkinsAuthenticationFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -@Path("/") -public interface SystemApi { - - @Named("system:info") - @Fallback(JenkinsFallbacks.SystemInfoOnError.class) - @ResponseParser(SystemInfoFromJenkinsHeaders.class) - @HEAD - SystemInfo systemInfo(); - - @Named("system:quiet-down") - @Path("quietDown") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Consumes(MediaType.TEXT_HTML) - @POST - RequestStatus quietDown(); - - @Named("system:cancel-quiet-down") - @Path("cancelQuietDown") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Consumes(MediaType.TEXT_HTML) - @POST - RequestStatus cancelQuietDown(); - -} diff --git a/src/main/java/com/cdancy/jenkins/rest/features/UserApi.java b/src/main/java/com/cdancy/jenkins/rest/features/UserApi.java deleted file mode 100644 index 5b4e573..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/features/UserApi.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.features; - -import javax.inject.Named; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.jclouds.Fallbacks; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.Payload; -import org.jclouds.rest.annotations.PayloadParam; -import org.jclouds.rest.annotations.RequestFilters; - -import com.cdancy.jenkins.rest.domain.user.ApiToken; -import com.cdancy.jenkins.rest.domain.user.User; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.fallbacks.JenkinsFallbacks; -import com.cdancy.jenkins.rest.filters.JenkinsAuthenticationFilter; -import com.cdancy.jenkins.rest.filters.JenkinsUserInjectionFilter; -import com.cdancy.jenkins.rest.parsers.RequestStatusParser; -import org.jclouds.rest.annotations.ResponseParser; - -/** - * The UserApi. - * - * Implements some of the User Rest Api defined in Jenkins. - * For the User Api, see User.java - * For the Api Token, see ApiTokenProperty.java. - */ -@RequestFilters({JenkinsAuthenticationFilter.class, JenkinsUserInjectionFilter.class}) -@Path("/user") -public interface UserApi { - - @Named("user:get") - @Path("/{user}/api/json") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @GET - User get(); - - @Named("user:generateNewToken") - @Path("/{user}/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken") - @Fallback(Fallbacks.NullOnNotFoundOr404.class) - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_FORM_URLENCODED) - @Payload("newTokenName={tokenName}") - @POST - ApiToken generateNewToken(@PayloadParam(value = "tokenName") String tokenName); - - @Named("user:revoke") - @Path("/{user}/descriptorByName/jenkins.security.ApiTokenProperty/revoke") - @Fallback(JenkinsFallbacks.RequestStatusOnError.class) - @ResponseParser(RequestStatusParser.class) - @Produces(MediaType.APPLICATION_FORM_URLENCODED) - @Payload("tokenUuid={tokenUuid}") - @POST - RequestStatus revoke(@PayloadParam(value = "tokenUuid") String tokenUuid); -} diff --git a/src/main/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilter.java b/src/main/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilter.java deleted file mode 100644 index 89f571d..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilter.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.filters; - -import java.util.Optional; -import javax.inject.Inject; -import javax.inject.Singleton; - -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.JenkinsAuthentication; -import com.cdancy.jenkins.rest.auth.AuthenticationType; -import com.cdancy.jenkins.rest.domain.crumb.Crumb; - -import org.jclouds.http.HttpException; -import org.jclouds.http.HttpRequest; -import org.jclouds.http.HttpRequestFilter; - -import com.google.common.net.HttpHeaders; - -import org.jclouds.rest.ResourceNotFoundException; - -@Singleton -public class JenkinsAuthenticationFilter implements HttpRequestFilter { - private final JenkinsAuthentication creds; - private final JenkinsApi jenkinsApi; - - // key = Crumb, value = true if exception is ResourceNotFoundException false otherwise - private volatile Pair crumbPair = null; - private static final String CRUMB_HEADER = "Jenkins-Crumb"; - - private static final String RNFSimpleName = ResourceNotFoundException.class.getSimpleName(); - - @Inject - JenkinsAuthenticationFilter(final JenkinsAuthentication creds, final JenkinsApi jenkinsApi) { - this.creds = creds; - this.jenkinsApi = jenkinsApi; - } - - @Override - public HttpRequest filter(final HttpRequest request) throws HttpException { - final HttpRequest.Builder> builder = request.toBuilder(); - - // Password and API Token are both Basic authentication (there is no Bearer authentication in Jenkins) - if (creds.authType() == AuthenticationType.UsernameApiToken || creds.authType() == AuthenticationType.UsernamePassword) { - final String authHeader = creds.authType().getAuthScheme() + " " + creds.authValue(); - builder.addHeader(HttpHeaders.AUTHORIZATION, authHeader); - } - - // Anon and Password need the crumb and the cookie when POSTing - if (request.getMethod().equals("POST") && - (creds.authType() == AuthenticationType.UsernamePassword || creds.authType() == AuthenticationType.Anonymous) - ) { - final Pair localCrumb = getCrumb(); - if (localCrumb.getKey().value() != null) { - builder.addHeader(CRUMB_HEADER, localCrumb.getKey().value()); - Optional.ofNullable(localCrumb.getKey().sessionIdCookie()) - .ifPresent(sessionId -> builder.addHeader(HttpHeaders.COOKIE, sessionId)); - } else { - if (!localCrumb.getValue()) { - throw new RuntimeException("Unexpected exception being thrown: error=" + localCrumb.getKey().errors().get(0)); - } - } - } - return builder.build(); - } - - private Pair getCrumb() { - Pair crumbValueInit = this.crumbPair; - if (crumbValueInit == null) { - synchronized(this) { - crumbValueInit = this.crumbPair; - if (crumbValueInit == null) { - final Crumb crumb = jenkinsApi.crumbIssuerApi().crumb(); - final Boolean isRNFE = crumb.errors().isEmpty() || crumb.errors().get(0).exceptionName().endsWith(RNFSimpleName); - this.crumbPair = crumbValueInit = new Pair<>(crumb, isRNFE); - } - } - } - return crumbValueInit; - } - - // simple impl/copy of javafx.util.Pair - private static class Pair { - private final A a; - private final B b; - public Pair(final A a, final B b) { - this.a = a; - this.b = b; - } - public A getKey() { - return a; - } - public B getValue() { - return b; - } - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/filters/ScrubNullFolderParam.java b/src/main/java/com/cdancy/jenkins/rest/filters/ScrubNullFolderParam.java deleted file mode 100644 index d4c1907..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/filters/ScrubNullFolderParam.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.filters; - -import org.jclouds.http.HttpException; -import org.jclouds.http.HttpRequest; -import org.jclouds.http.HttpRequestFilter; - -import javax.inject.Singleton; - -import static com.cdancy.jenkins.rest.JenkinsConstants.OPTIONAL_FOLDER_PATH_PARAM; - -@Singleton -public class ScrubNullFolderParam implements HttpRequestFilter { - - private static final String SCRUB_NULL_PARAM = "/%7B" + OPTIONAL_FOLDER_PATH_PARAM + "%7D"; - private static final String EMPTY_STRING = ""; - - @Override - public HttpRequest filter(final HttpRequest request) throws HttpException { - final String requestPath = request.getEndpoint().getRawPath().replaceAll(SCRUB_NULL_PARAM, EMPTY_STRING); - return request.toBuilder().fromHttpRequest(request).replacePath(requestPath).build(); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/handlers/JenkinsErrorHandler.java b/src/main/java/com/cdancy/jenkins/rest/handlers/JenkinsErrorHandler.java deleted file mode 100644 index 1fb9f7e..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/handlers/JenkinsErrorHandler.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.handlers; - -import static org.jclouds.util.Closeables2.closeQuietly; - -import com.cdancy.jenkins.rest.exception.ForbiddenException; -import com.cdancy.jenkins.rest.exception.MethodNotAllowedException; -import com.cdancy.jenkins.rest.exception.RedirectTo404Exception; -import com.cdancy.jenkins.rest.exception.UnsupportedMediaTypeException; - -import java.io.IOException; - -import org.jclouds.http.HttpCommand; -import org.jclouds.http.HttpErrorHandler; -import org.jclouds.http.HttpResponse; -import org.jclouds.http.HttpResponseException; -import org.jclouds.rest.ResourceAlreadyExistsException; -import org.jclouds.rest.ResourceNotFoundException; -import org.jclouds.rest.AuthorizationException; -import org.jclouds.util.Strings2; - -import com.google.common.base.Throwables; - -/** - * Handle errors and propagate exception - */ -public class JenkinsErrorHandler implements HttpErrorHandler { - - @Override - public void handleError(final HttpCommand command, final HttpResponse response) { - - Exception exception = null; - try { - final String message = parseMessage(command, response); - - switch (response.getStatusCode()) { - case 400: - if (command.getCurrentRequest().getMethod().equals("POST")) { - if (command.getCurrentRequest().getRequestLine().contains("/createItem")) { - if (message.contains("A job already exists with the name")) { - exception = new ResourceAlreadyExistsException(message); - break; - } - } - } - exception = new IllegalArgumentException(message); - break; - case 401: - exception = new AuthorizationException(message); - break; - case 403: - exception = new ForbiddenException(message); - break; - case 404: - // When Jenkins replies to term or kill with a redirect to a non-existent URL - // we want to return a custom error message and avoid an exception in the user code. - if (command.getCurrentRequest().getMethod().equals("POST")) { - final String path = command.getCurrentRequest().getEndpoint().getPath(); - if (path.endsWith("/term/")) { - exception = new RedirectTo404Exception("The term operation does not exist for " + command.getCurrentRequest().getEndpoint().toString() + ", try stop instead."); - break; - } else if (path.endsWith("/kill/")) { - exception = new RedirectTo404Exception("The kill operation does not exist for " + command.getCurrentRequest().getEndpoint().toString() + ", try stop instead."); - break; - } - } - exception = new ResourceNotFoundException(message); - break; - case 405: - exception = new MethodNotAllowedException(message); - break; - case 409: - exception = new ResourceAlreadyExistsException(message); - break; - case 415: - exception = new UnsupportedMediaTypeException(message); - break; - default: - exception = new HttpResponseException(command, response); - } - } catch (Exception e) { - exception = new HttpResponseException(command, response, e); - } finally { - closeQuietly(response.getPayload()); - command.setException(exception); - } - } - - private String parseMessage(final HttpCommand command, final HttpResponse response) { - if (response.getPayload() != null) { - try { - return Strings2.toStringAndClose(response.getPayload().openStream()); - } catch (IOException e) { - throw Throwables.propagate(e); - } - } else { - final String errorMessage = response.getFirstHeaderOrNull("X-Error"); - return command.getCurrentRequest().getRequestLine() + - " -> " + - response.getStatusLine() + - " -> " + - (errorMessage != null ? errorMessage : ""); - } - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/parsers/BuildNumberToInteger.java b/src/main/java/com/cdancy/jenkins/rest/parsers/BuildNumberToInteger.java deleted file mode 100644 index 056fec5..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/parsers/BuildNumberToInteger.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.parsers; - -import java.io.InputStream; -import java.io.InputStreamReader; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpResponse; - -import com.google.common.base.Charsets; -import com.google.common.base.Function; -import com.google.common.base.Throwables; -import com.google.common.io.CharStreams; - -/** - * Created by dancc on 3/11/16. - */ -@Singleton -public class BuildNumberToInteger implements Function { - - public Integer apply(HttpResponse response) { - return Integer.valueOf(getTextOutput(response)); - } - - public String getTextOutput(HttpResponse response) { - InputStream is = null; - try { - is = response.getPayload().openStream(); - return CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8)).trim(); - } catch (Exception e) { - Throwables.propagate(e); - } finally { - if (is != null) { - try { - is.close(); - } catch (Exception e) { - Throwables.propagate(e); - } - } - } - - return null; - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/parsers/CrumbParser.java b/src/main/java/com/cdancy/jenkins/rest/parsers/CrumbParser.java deleted file mode 100644 index c169799..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/parsers/CrumbParser.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.parsers; - -import static com.cdancy.jenkins.rest.JenkinsConstants.JENKINS_COOKIES_JSESSIONID; - -import com.cdancy.jenkins.rest.domain.crumb.Crumb; - -import com.google.common.base.Function; -import java.io.IOException; -import java.util.Collection; - -import javax.inject.Singleton; -import javax.ws.rs.core.HttpHeaders; - -import org.jclouds.http.HttpResponse; -import org.jclouds.util.Strings2; - -/** - * Turn a valid response, but one that has no body, into a Crumb. - */ -@Singleton -public class CrumbParser implements Function { - - @Override - public Crumb apply(final HttpResponse input) { - if (input == null) { - throw new RuntimeException("Unexpected NULL HttpResponse object"); - } - - final int statusCode = input.getStatusCode(); - if (statusCode >= 200 && statusCode < 400) { - try { - return Crumb.create(crumbValue(input), sessionIdCookie(input)); - } catch (final IOException e) { - throw new RuntimeException(input.getStatusLine(), e); - } - } else { - throw new RuntimeException(input.getStatusLine()); - } - } - - private static String crumbValue(HttpResponse input) throws IOException { - return Strings2.toStringAndClose(input.getPayload().openStream()) - .split(":")[1]; - } - - private static String sessionIdCookie(HttpResponse input) { - return setCookieValues(input).stream() - .filter(c -> c.startsWith(JENKINS_COOKIES_JSESSIONID)) - .findFirst() - .orElse(""); - } - - private static Collection setCookieValues(HttpResponse input) { - Collection setCookieValues = input.getHeaders().get(HttpHeaders.SET_COOKIE); - if(setCookieValues.isEmpty()) { - return input.getHeaders().get(HttpHeaders.SET_COOKIE.toLowerCase()); - } else { - return setCookieValues; - } - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/parsers/FolderPathParser.java b/src/main/java/com/cdancy/jenkins/rest/parsers/FolderPathParser.java deleted file mode 100644 index 07c2109..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/parsers/FolderPathParser.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.cdancy.jenkins.rest.parsers; - -import com.google.common.base.Function; - -import javax.inject.Singleton; - -/* - * Turn the optionalFolderPath param to jenkins URL style - */ -@Singleton -public class FolderPathParser implements Function { - - public static final String EMPTY_STRING = ""; - public static final String FOLDER_NAME_PREFIX = "job/"; - public static final Character FOLDER_NAME_SEPARATOR = '/'; - - @Override - public String apply(Object folderPath) { - if(folderPath == null) { - return EMPTY_STRING; - } - - final StringBuilder path = new StringBuilder((String) folderPath); - if (path.length() == 0) { - return EMPTY_STRING; - } - - if(path.charAt(0) == FOLDER_NAME_SEPARATOR){ - path.deleteCharAt(0); - } - if (path.length() == 0) { - return EMPTY_STRING; - } - - if(path.charAt(path.length() - 1) == FOLDER_NAME_SEPARATOR) { - path.deleteCharAt(path.length() - 1); - } - if (path.length() == 0) { - return EMPTY_STRING; - } - - final String[] folders = path.toString().split(Character.toString(FOLDER_NAME_SEPARATOR)); - path.setLength(0); - for(final String folder : folders) { - path.append(FOLDER_NAME_PREFIX).append(folder).append(FOLDER_NAME_SEPARATOR); - } - return path.toString(); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/parsers/LocationToQueueId.java b/src/main/java/com/cdancy/jenkins/rest/parsers/LocationToQueueId.java deleted file mode 100644 index 15b9174..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/parsers/LocationToQueueId.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.parsers; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpResponse; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; - -import com.cdancy.jenkins.rest.domain.common.Error; -import com.cdancy.jenkins.rest.domain.common.IntegerResponse; - -/** - * Created by dancc on 3/11/16. - */ -@Singleton -public class LocationToQueueId implements Function { - - private static final Pattern pattern = Pattern.compile("^.*/queue/item/(\\d+)/$"); - - public IntegerResponse apply(HttpResponse response) { - if (response == null) { - throw new RuntimeException("Unexpected NULL HttpResponse object"); - } - - String url = response.getFirstHeaderOrNull("Location"); - if (url != null) { - Matcher matcher = pattern.matcher(url); - if (matcher.find() && matcher.groupCount() == 1) { - return IntegerResponse.create(Integer.valueOf(matcher.group(1)), null); - } - } - final Error error = Error.create(null, - "No queue item Location header could be found despite getting a valid HTTP response.", - NumberFormatException.class.getCanonicalName()); - return IntegerResponse.create(null, Lists.newArrayList(error)); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/parsers/OptionalFolderPathParser.java b/src/main/java/com/cdancy/jenkins/rest/parsers/OptionalFolderPathParser.java deleted file mode 100644 index 09f7527..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/parsers/OptionalFolderPathParser.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.cdancy.jenkins.rest.parsers; - -import com.google.common.base.Function; - -import javax.inject.Singleton; - -/* - * Turn the optionalFolderPath param to jenkins URL style - */ -@Singleton -public class OptionalFolderPathParser implements Function { - - public static final String EMPTY_STRING = ""; - public static final String FOLDER_NAME_PREFIX = "job/"; - public static final Character FOLDER_NAME_SEPARATOR = '/'; - - @Override - public String apply(Object optionalFolderPath) { - if(optionalFolderPath == null) { - return EMPTY_STRING; - } - - final StringBuilder path = new StringBuilder((String) optionalFolderPath); - if (path.length() == 0) { - return EMPTY_STRING; - } - - if(path.charAt(0) == FOLDER_NAME_SEPARATOR){ - path.deleteCharAt(0); - } - if (path.length() == 0) { - return EMPTY_STRING; - } - - if(path.charAt(path.length() - 1) == FOLDER_NAME_SEPARATOR) { - path.deleteCharAt(path.length() - 1); - } - if (path.length() == 0) { - return EMPTY_STRING; - } - - final String[] folders = path.toString().split(Character.toString(FOLDER_NAME_SEPARATOR)); - path.setLength(0); - for(final String folder : folders) { - path.append(FOLDER_NAME_PREFIX).append(folder).append(FOLDER_NAME_SEPARATOR); - } - - return path.toString(); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/parsers/OutputToProgressiveText.java b/src/main/java/com/cdancy/jenkins/rest/parsers/OutputToProgressiveText.java deleted file mode 100644 index 4dcd8a8..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/parsers/OutputToProgressiveText.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.parsers; - -import java.io.InputStream; -import java.io.InputStreamReader; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpResponse; - -import com.cdancy.jenkins.rest.domain.job.ProgressiveText; -import com.google.common.base.Charsets; -import com.google.common.base.Function; -import com.google.common.io.CharStreams; - -/** - * Created by dancc on 3/11/16. - */ -@Singleton -public class OutputToProgressiveText implements Function { - - public ProgressiveText apply(HttpResponse response) { - - String text = getTextOutput(response); - int size = getTextSize(response); - boolean hasMoreData = getMoreData(response); - return ProgressiveText.create(text, size, hasMoreData); - } - - public String getTextOutput(HttpResponse response) { - try (InputStream is = response.getPayload().openStream()) { - return CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8)); - } catch (Exception e) { - // ignore - } - // ignore - - return null; - } - - public int getTextSize(HttpResponse response) { - String textSize = response.getFirstHeaderOrNull("X-Text-Size"); - return textSize != null ? Integer.parseInt(textSize) : -1; - } - - public boolean getMoreData(HttpResponse response) { - String moreData = response.getFirstHeaderOrNull("X-More-Data"); - return Boolean.parseBoolean(moreData); - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/parsers/RequestStatusParser.java b/src/main/java/com/cdancy/jenkins/rest/parsers/RequestStatusParser.java deleted file mode 100644 index 38f491b..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/parsers/RequestStatusParser.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.parsers; - -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.google.common.base.Function; -import javax.inject.Singleton; -import org.jclouds.http.HttpResponse; - -/** - * Turn a valid response, but one that has no body, into a RequestStatus. - */ -@Singleton -public class RequestStatusParser implements Function { - - @Override - public RequestStatus apply(final HttpResponse input) { - if (input == null) { - throw new RuntimeException("Unexpected NULL HttpResponse object"); - } - - final int statusCode = input.getStatusCode(); - if (statusCode >= 200 && statusCode < 400) { - return RequestStatus.create(true, null); - } else { - throw new RuntimeException(input.getStatusLine()); - } - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/parsers/SystemInfoFromJenkinsHeaders.java b/src/main/java/com/cdancy/jenkins/rest/parsers/SystemInfoFromJenkinsHeaders.java deleted file mode 100644 index cb14ee0..0000000 --- a/src/main/java/com/cdancy/jenkins/rest/parsers/SystemInfoFromJenkinsHeaders.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.parsers; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpResponse; - -import com.cdancy.jenkins.rest.domain.system.SystemInfo; - -import com.google.common.base.Function; - -/** - * Created by dancc on 3/11/16. - */ -@Singleton -public class SystemInfoFromJenkinsHeaders implements Function { - - @Override - public SystemInfo apply(HttpResponse response) { - if (response == null) { - throw new RuntimeException("Unexpected NULL HttpResponse object"); - } - - final int statusCode = response.getStatusCode(); - if (statusCode >= 200 && statusCode < 400) { - return SystemInfo.create(response.getFirstHeaderOrNull("X-Hudson"), response.getFirstHeaderOrNull("X-Jenkins"), - response.getFirstHeaderOrNull("X-Jenkins-Session"), - response.getFirstHeaderOrNull("X-Instance-Identity"), response.getFirstHeaderOrNull("X-SSH-Endpoint"), - response.getFirstHeaderOrNull("Server"), null); - } else { - throw new RuntimeException(response.getStatusLine()); - } - } -} diff --git a/src/main/java/com/cdancy/jenkins/rest/JenkinsApi.java b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsApi.java similarity index 63% rename from src/main/java/com/cdancy/jenkins/rest/JenkinsApi.java rename to src/main/java/io/github/hmedioni/jenkins/client/JenkinsApi.java index b87877b..b5c9ca9 100644 --- a/src/main/java/com/cdancy/jenkins/rest/JenkinsApi.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsApi.java @@ -15,44 +15,36 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest; +package io.github.hmedioni.jenkins.client; -import java.io.Closeable; +import io.github.hmedioni.jenkins.client.features.*; +import lombok.experimental.*; -import org.jclouds.rest.annotations.Delegate; - -import com.cdancy.jenkins.rest.features.ConfigurationAsCodeApi; -import com.cdancy.jenkins.rest.features.CrumbIssuerApi; -import com.cdancy.jenkins.rest.features.JobsApi; -import com.cdancy.jenkins.rest.features.PluginManagerApi; -import com.cdancy.jenkins.rest.features.QueueApi; -import com.cdancy.jenkins.rest.features.StatisticsApi; -import com.cdancy.jenkins.rest.features.SystemApi; -import com.cdancy.jenkins.rest.features.UserApi; +import java.io.*; public interface JenkinsApi extends Closeable { - @Delegate + CrumbIssuerApi crumbIssuerApi(); - @Delegate + JobsApi jobsApi(); - @Delegate + PluginManagerApi pluginManagerApi(); - @Delegate + QueueApi queueApi(); - @Delegate + StatisticsApi statisticsApi(); - @Delegate + SystemApi systemApi(); - @Delegate + ConfigurationAsCodeApi configurationAsCodeApi(); - @Delegate + UserApi userApi(); } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/JenkinsApiClientImpl.java b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsApiClientImpl.java new file mode 100644 index 0000000..ce63089 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsApiClientImpl.java @@ -0,0 +1,122 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client; + +import io.github.hmedioni.jenkins.client.config.*; +import io.github.hmedioni.jenkins.client.features.*; +import io.github.hmedioni.jenkins.client.filters.*; +import io.github.hmedioni.jenkins.client.handlers.*; +import lombok.experimental.*; +import org.springframework.web.reactive.function.client.*; +import org.springframework.web.reactive.function.client.support.*; +import org.springframework.web.service.invoker.*; +import org.springframework.web.util.*; + +import java.io.*; +import java.util.*; + +import static org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode.TEMPLATE_AND_VALUES; + +public class JenkinsApiClientImpl implements JenkinsApi { + + private final JenkinsProperties jenkinsProperties; + private final WebClient webClient; + private final HttpServiceProxyFactory httpServiceProxyFactory; + private final Map, Object> singletons; + + public JenkinsApiClientImpl(JenkinsProperties jenkinsProperties, WebClient webClient) { + this.jenkinsProperties = jenkinsProperties; + this.webClient = webClient; + this.httpServiceProxyFactory = buildHttpServiceProxyFactory(jenkinsProperties, webClient, TEMPLATE_AND_VALUES); + this.singletons = Collections.synchronizedMap(new HashMap<>()); + } + + private static HttpServiceProxyFactory buildHttpServiceProxyFactory(JenkinsProperties jenkinsProperties, WebClient webClient, + DefaultUriBuilderFactory.EncodingMode encodingMode) { + JenkinsAuthenticationFilter bitbucketAuthenticationFilter = new JenkinsAuthenticationFilter(jenkinsProperties.jenkinsAuthentication()); + ScrubNullFolderParam scrubNullFromPathFilter = new ScrubNullFolderParam(); + if (webClient == null) { + DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(jenkinsProperties.getUrl()); + factory.setEncodingMode(encodingMode); + + webClient = WebClient.builder() + .uriBuilderFactory(factory) + .filter(bitbucketAuthenticationFilter) + .filter(scrubNullFromPathFilter) + .filter(JenkinsErrorHandler.handler()) + .build(); + } + return HttpServiceProxyFactory.builderFor(WebClientAdapter.create(webClient)) + .build(); + } + + + private synchronized T getSingleton(Class klass, Object o) { + return klass.cast(singletons.computeIfAbsent(klass, aClass -> o)); + } + + private synchronized T getSingleton(Class klass) { + return klass.cast(singletons.computeIfAbsent(klass, httpServiceProxyFactory::createClient)); + } + + + @Override + public CrumbIssuerApi crumbIssuerApi() { + return getSingleton(CrumbIssuerApi.class); + } + + @Override + public JobsApi jobsApi() { + return getSingleton(JobsApi.class); + } + + @Override + public PluginManagerApi pluginManagerApi() { + return getSingleton(PluginManagerApi.class); + } + + @Override + public QueueApi queueApi() { + return getSingleton(QueueApi.class); + } + + @Override + public StatisticsApi statisticsApi() { + return getSingleton(StatisticsApi.class); + } + + @Override + public SystemApi systemApi() { + return getSingleton(SystemApi.class); + } + + @Override + public ConfigurationAsCodeApi configurationAsCodeApi() { + return getSingleton(ConfigurationAsCodeApi.class); + } + + @Override + public UserApi userApi() { + return getSingleton(UserApi.class); + } + + @Override + public void close() throws IOException { + + } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/common/ErrorsHolder.java b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsApiMetadata.java similarity index 68% rename from src/main/java/com/cdancy/jenkins/rest/domain/common/ErrorsHolder.java rename to src/main/java/io/github/hmedioni/jenkins/client/JenkinsApiMetadata.java index 85c3d26..42eb2e5 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/common/ErrorsHolder.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsApiMetadata.java @@ -15,16 +15,15 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.common; +package io.github.hmedioni.jenkins.client; -import java.util.List; +import java.net.*; +import java.util.*; + +public class JenkinsApiMetadata { + + public static final String API_VERSION = "1.0"; + public static final String BUILD_VERSION = "2.0"; -/** - * This interface should NOT be applied to "option" like classes and/or used - * in instances where this is applied to outgoing http traffic. This interface - * should ONLY be used for classes modeled after incoming http traffic. - */ -public interface ErrorsHolder { - List errors(); } diff --git a/src/main/java/com/cdancy/jenkins/rest/JenkinsAuthentication.java b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsAuthentication.java similarity index 74% rename from src/main/java/com/cdancy/jenkins/rest/JenkinsAuthentication.java rename to src/main/java/io/github/hmedioni/jenkins/client/JenkinsAuthentication.java index dc05838..8ad0f4a 100644 --- a/src/main/java/com/cdancy/jenkins/rest/JenkinsAuthentication.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsAuthentication.java @@ -15,35 +15,41 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest; +package io.github.hmedioni.jenkins.client; -import static com.google.common.io.BaseEncoding.base64; -import com.cdancy.jenkins.rest.auth.AuthenticationType; -import com.cdancy.jenkins.rest.exception.UndetectableIdentityException; +import io.github.hmedioni.jenkins.client.auth.*; +import io.github.hmedioni.jenkins.client.exception.*; +import lombok.*; +import org.springframework.lang.*; +import org.springframework.web.reactive.function.client.*; -import java.nio.charset.StandardCharsets; -import java.util.Objects; +import java.nio.charset.*; +import java.util.*; -import org.jclouds.domain.Credentials; -import org.jclouds.javax.annotation.Nullable; /** * Credentials instance for Jenkins authentication. */ -public class JenkinsAuthentication extends Credentials { +@EqualsAndHashCode(callSuper = true) +@Data +public class JenkinsAuthentication extends ExchangeFilterFunctions { private final AuthenticationType authType; + private final String encodedCred; + /** * Create instance of JenkinsAuthentication. * - * @param identity the identity of the credential, this would be the username for the password or the api token or the base64 encoded value. - * @param credential the username:password, or the username:apiToken, or their base64 encoded value. This is base64 encoded before being stored. * @param authType authentication type (e.g. UsernamePassword, UsernameApiToken, Anonymous). */ - private JenkinsAuthentication(final String identity, final String credential, final AuthenticationType authType) { - super(identity, credential.contains(":") ? base64().encode(credential.getBytes()) : credential); + public JenkinsAuthentication(final String authValue, final AuthenticationType authType) { + if (authType == AuthenticationType.USERNAME_PASSWORD || authType == AuthenticationType.USERNAME_API_TOKEN) { + this.encodedCred = Base64.getEncoder().encodeToString(authValue.getBytes()); + } else { + this.encodedCred = ""; + } this.authType = authType; } @@ -54,7 +60,7 @@ private JenkinsAuthentication(final String identity, final String credential, fi */ @Nullable public String authValue() { - return this.credential; + return this.encodedCred; } /** @@ -66,15 +72,11 @@ public AuthenticationType authType() { return authType; } - public static Builder builder() { - return new Builder(); - } - public static class Builder { private String identity = "anonymous"; private String credential = identity + ":"; - private AuthenticationType authType = AuthenticationType.Anonymous; + private AuthenticationType authType = AuthenticationType.ANONYMOUS; /** * Set 'UsernamePassword' credentials. @@ -85,7 +87,7 @@ public static class Builder { public Builder credentials(final String usernamePassword) { this.identity = Objects.requireNonNull(extractIdentity(usernamePassword)); this.credential = Objects.requireNonNull(usernamePassword); - this.authType = AuthenticationType.UsernamePassword; + this.authType = AuthenticationType.USERNAME_PASSWORD; return this; } @@ -98,13 +100,13 @@ public Builder credentials(final String usernamePassword) { public Builder apiToken(final String apiTokenCredentials) { this.identity = Objects.requireNonNull(extractIdentity(apiTokenCredentials)); this.credential = Objects.requireNonNull(apiTokenCredentials); - this.authType = AuthenticationType.UsernameApiToken; + this.authType = AuthenticationType.USERNAME_API_TOKEN; return this; } /** * Extract the identity from the credential. - * + *

* The credential is entered by the user in one of two forms: *

    *
  1. Colon separated form: username:password or username:password @@ -115,7 +117,7 @@ public Builder apiToken(final String apiTokenCredentials) { private String extractIdentity(final String credentialString) { String decoded; if (!credentialString.contains(":")) { - decoded = new String(base64().decode(credentialString),StandardCharsets.UTF_8); + decoded = new String(Base64.getDecoder().decode(credentialString), StandardCharsets.UTF_8); } else { decoded = credentialString; } @@ -128,13 +130,13 @@ private String extractIdentity(final String credentialString) { return decoded.split(":")[0]; } - /** + /** * Build and instance of JenkinsCredentials. * * @return instance of JenkinsCredentials. */ public JenkinsAuthentication build() { - return new JenkinsAuthentication(identity, credential, authType); + return new JenkinsAuthentication(credential, authType); } } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/JenkinsClient.java b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsClient.java new file mode 100644 index 0000000..66c54ab --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsClient.java @@ -0,0 +1,85 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client; + + +import io.github.hmedioni.jenkins.client.auth.*; +import io.github.hmedioni.jenkins.client.config.*; +import lombok.*; +import org.springframework.lang.*; +import org.springframework.web.reactive.function.client.*; + +import java.io.*; + +public final class JenkinsClient implements Closeable { + + @Getter + private final JenkinsAuthentication jenkinsAuthentication; + private final JenkinsApi jenkinsApi; + + /** + * Create a JenkinsClient inferring endpoint and authentication from + * environment and system properties. + */ + public static JenkinsClient create(JenkinsProperties jenkinsProperties) { + return new JenkinsClient(jenkinsProperties, jenkinsApi(jenkinsProperties, null)); + } + + public static JenkinsClient create(JenkinsProperties jenkinsProperties, WebClient webClient) { + return new JenkinsClient(jenkinsProperties, jenkinsApi(jenkinsProperties, webClient)); + } + + private static JenkinsApi jenkinsApi(JenkinsProperties jenkinsProperties, WebClient webClient) { + return new JenkinsApiClientImpl(jenkinsProperties, webClient); + } + + private JenkinsClient(@Nullable JenkinsProperties jenkinsProperties, JenkinsApi jenkinsApi) { + JenkinsAuthentication jenkinsAuthentication1; + if (jenkinsProperties != null) { + if (jenkinsProperties.getUrl() == null) { + jenkinsProperties.setUrl(JenkinsUtils.inferEndpoint()); + } + if (jenkinsProperties.getUser() == null) { + jenkinsAuthentication1 = JenkinsUtils.inferAuthentication(); + } else { + jenkinsAuthentication1 = new JenkinsAuthentication(jenkinsProperties.getUser() + ":" + jenkinsProperties.getPassword(), + AuthenticationType.USERNAME_PASSWORD); + } + } else { + jenkinsProperties = new JenkinsProperties(); + jenkinsProperties.setUrl(JenkinsUtils.inferEndpoint()); + jenkinsAuthentication1 = JenkinsUtils.inferAuthentication(); + } + this.jenkinsAuthentication = jenkinsAuthentication1; + this.jenkinsApi = jenkinsApi; + } + + + + public JenkinsApi api() { + return this.jenkinsApi; + } + + @Override + public void close() throws IOException { + if (this.api() != null) { + this.api().close(); + } + } + +} diff --git a/src/main/java/com/cdancy/jenkins/rest/JenkinsConstants.java b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsConstants.java similarity index 98% rename from src/main/java/com/cdancy/jenkins/rest/JenkinsConstants.java rename to src/main/java/io/github/hmedioni/jenkins/client/JenkinsConstants.java index 91877fa..0de4476 100644 --- a/src/main/java/com/cdancy/jenkins/rest/JenkinsConstants.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsConstants.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest; +package io.github.hmedioni.jenkins.client; /** * Various constants that can be used in a global context. diff --git a/src/main/java/com/cdancy/jenkins/rest/JenkinsUtils.java b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsUtils.java similarity index 64% rename from src/main/java/com/cdancy/jenkins/rest/JenkinsUtils.java rename to src/main/java/io/github/hmedioni/jenkins/client/JenkinsUtils.java index 5b56746..603d53e 100644 --- a/src/main/java/com/cdancy/jenkins/rest/JenkinsUtils.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/JenkinsUtils.java @@ -1,53 +1,12 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest; - -import static com.cdancy.jenkins.rest.JenkinsConstants.JENKINS_REST_PROPERTY_ID; -import static com.cdancy.jenkins.rest.JenkinsConstants.JENKINS_REST_VARIABLE_ID; -import static com.cdancy.jenkins.rest.JenkinsConstants.CREDENTIALS_ENVIRONMENT_VARIABLE; -import static com.cdancy.jenkins.rest.JenkinsConstants.CREDENTIALS_SYSTEM_PROPERTY; -import static com.cdancy.jenkins.rest.JenkinsConstants.DEFAULT_ENDPOINT; -import static com.cdancy.jenkins.rest.JenkinsConstants.ENDPOINT_ENVIRONMENT_VARIABLE; -import static com.cdancy.jenkins.rest.JenkinsConstants.ENDPOINT_SYSTEM_PROPERTY; -import static com.cdancy.jenkins.rest.JenkinsConstants.JCLOUDS_PROPERTY_ID; -import static com.cdancy.jenkins.rest.JenkinsConstants.JCLOUDS_VARIABLE_ID; -import static com.cdancy.jenkins.rest.JenkinsConstants.API_TOKEN_ENVIRONMENT_VARIABLE; -import static com.cdancy.jenkins.rest.JenkinsConstants.API_TOKEN_SYSTEM_PROPERTY; +package io.github.hmedioni.jenkins.client; -import com.google.common.base.Throwables; +import org.springframework.lang.*; +import reactor.core.*; -import java.util.List; -import java.util.Map; +import java.lang.reflect.*; +import java.util.*; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import java.lang.reflect.Field; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Objects; -import java.util.Properties; - -import org.jclouds.javax.annotation.Nullable; +import static io.github.hmedioni.jenkins.client.JenkinsConstants.*; /** * Collection of static methods to be used globally. @@ -56,30 +15,32 @@ public class JenkinsUtils { // global gson parser object - public static final Gson GSON_PARSER = new Gson(); - public static final JsonParser JSON_PARSER = new JsonParser(); + + protected JenkinsUtils() { + throw new UnsupportedOperationException("Purposefully not implemented"); + } /** * Convert passed Iterable into an ImmutableList. * - * @param an arbitrary type. + * @param an arbitrary type. * @param input the Iterable to copy. * @return ImmutableList or empty ImmutableList if `input` is null. */ - public static List nullToEmpty(final Iterable input) { - return input == null ? ImmutableList.of() : ImmutableList.copyOf(input); + public static List nullToEmpty(final Collection input) { + return input == null ? List.of() : List.copyOf(input); } /** * Convert passed Map into an ImmutableMap. * - * @param an arbitrary type. - * @param an arbitrary type. + * @param an arbitrary type. + * @param an arbitrary type. * @param input the Map to copy. * @return ImmutableMap or empty ImmutableMap if `input` is null. */ public static Map nullToEmpty(final Map input) { - return input == null ? ImmutableMap.of() : ImmutableMap.copyOf(input); + return input == null ? Map.of() : Map.copyOf(input); } /** @@ -88,9 +49,6 @@ public static Map nullToEmpty(final Map i * @param input the Map to convert. * @return JsonElement or empty JsonElement if `input` is null. */ - public static JsonElement nullToJsonElement(final Map input) { - return GSON_PARSER.toJsonTree(nullToEmpty(input)); - } /** * Convert passed Map into a JsonElement. @@ -98,9 +56,6 @@ public static JsonElement nullToJsonElement(final Map input) { * @param input the Map to convert. * @return JsonElement or empty JsonElement if `input` is null. */ - public static JsonElement nullToJsonElement(final JsonElement input) { - return input != null ? input : GSON_PARSER.toJsonTree(ImmutableMap.of()); - } /** * Convert passed String into a JsonElement. @@ -108,9 +63,6 @@ public static JsonElement nullToJsonElement(final JsonElement input) { * @param input the String to convert. * @return JsonElement or empty JsonElement if `input` is null. */ - public static JsonElement nullToJsonElement(final String input) { - return JSON_PARSER.parse(input != null ? input : "{}"); - } /** * If the passed systemProperty is non-null we will attempt to query @@ -119,12 +71,12 @@ public static JsonElement nullToJsonElement(final String input) { * query the `Environment Variables` for a value and return it. If * both are either null or can't be found than null will be returned. * - * @param systemProperty possibly existent System Property. + * @param systemProperty possibly existent System Property. * @param environmentVariable possibly existent Environment Variable. * @return found external value or null. */ public static String retriveExternalValue(@Nullable final String systemProperty, - @Nullable final String environmentVariable) { + @Nullable final String environmentVariable) { // 1.) Search for System Property if (systemProperty != null) { @@ -136,9 +88,7 @@ public static String retriveExternalValue(@Nullable final String systemProperty, if (environmentVariable != null) { final String value = System.getenv().get(environmentVariable); - if (value != null) { - return value; - } + return value; } return null; @@ -153,8 +103,8 @@ public static String retriveExternalValue(@Nullable final String systemProperty, */ public static String inferEndpoint() { final String possibleValue = JenkinsUtils - .retriveExternalValue(ENDPOINT_SYSTEM_PROPERTY, - ENDPOINT_ENVIRONMENT_VARIABLE); + .retriveExternalValue(ENDPOINT_SYSTEM_PROPERTY, + ENDPOINT_ENVIRONMENT_VARIABLE); return possibleValue != null ? possibleValue : DEFAULT_ENDPOINT; } @@ -165,11 +115,11 @@ public static String inferEndpoint() { */ public static JenkinsAuthentication inferAuthentication() { - final JenkinsAuthentication.Builder inferAuth = JenkinsAuthentication.builder(); + final JenkinsAuthentication.Builder inferAuth = new JenkinsAuthentication.Builder(); // 1.) Check for API Token as this requires no crumb hence is faster String authValue = JenkinsUtils - .retriveExternalValue(API_TOKEN_SYSTEM_PROPERTY, - API_TOKEN_ENVIRONMENT_VARIABLE); + .retriveExternalValue(API_TOKEN_SYSTEM_PROPERTY, + API_TOKEN_ENVIRONMENT_VARIABLE); if (authValue != null) { inferAuth.apiToken(authValue); return inferAuth.build(); @@ -177,8 +127,8 @@ public static JenkinsAuthentication inferAuthentication() { // 2.) Check for UsernamePassword auth credentials. authValue = JenkinsUtils - .retriveExternalValue(CREDENTIALS_SYSTEM_PROPERTY, - CREDENTIALS_ENVIRONMENT_VARIABLE); + .retriveExternalValue(CREDENTIALS_SYSTEM_PROPERTY, + CREDENTIALS_ENVIRONMENT_VARIABLE); if (authValue != null) { inferAuth.credentials(authValue); return inferAuth.build(); @@ -204,7 +154,7 @@ public static Properties inferOverrides() { final String key = enums.nextElement(); if (key.startsWith(JENKINS_REST_PROPERTY_ID)) { final int index = key.indexOf(JCLOUDS_PROPERTY_ID); - final String trimmedKey = key.substring(index, key.length()); + final String trimmedKey = key.substring(index); overrides.put(trimmedKey, systemProperties.getProperty(key)); } } @@ -216,9 +166,9 @@ public static Properties inferOverrides() { if (entry.getKey().startsWith(JENKINS_REST_VARIABLE_ID)) { final int index = entry.getKey().indexOf(JCLOUDS_VARIABLE_ID); final String trimmedKey = entry.getKey() - .substring(index, entry.getKey().length()) - .toLowerCase() - .replaceAll("_", "."); + .substring(index) + .toLowerCase() + .replaceAll("_", "."); if (!overrides.containsKey(trimmedKey)) { overrides.put(trimmedKey, entry.getValue()); } @@ -235,7 +185,7 @@ public static Properties inferOverrides() { */ public static void addEnvironmentVariables(final Map addEnvVars) { Objects.requireNonNull(addEnvVars, "Must pass non-null Map"); - final Map newenv = Maps.newHashMap(System.getenv()); + final Map newenv = System.getenv(); newenv.putAll(addEnvVars); setEnvironmentVariables(newenv); } @@ -247,7 +197,7 @@ public static void addEnvironmentVariables(final Map addEnvVars) */ public static void removeEnvironmentVariables(final Collection removeEnvVars) { Objects.requireNonNull(removeEnvVars, "Must pass non-null Collection"); - final Map newenv = Maps.newHashMap(System.getenv()); + final Map newenv = System.getenv(); newenv.keySet().removeAll(removeEnvVars); setEnvironmentVariables(newenv); } @@ -270,7 +220,8 @@ public static void setEnvironmentVariables(final Map newEnvVars) theCaseInsensitiveEnvironmentField.setAccessible(true); final Map cienv = (Map) theCaseInsensitiveEnvironmentField.get(null); cienv.putAll(newEnvVars); - } catch (final ClassNotFoundException | IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException e) { + } catch (final ClassNotFoundException | IllegalAccessException | IllegalArgumentException | + NoSuchFieldException | SecurityException e) { final Class[] classes = Collections.class.getDeclaredClasses(); final Map env = System.getenv(); for (final Class cl : classes) { @@ -283,14 +234,10 @@ public static void setEnvironmentVariables(final Map newEnvVars) map.clear(); map.putAll(newEnvVars); } catch (final NoSuchFieldException | IllegalAccessException e2) { - throw Throwables.propagate(e2); + throw Exceptions.propagate(e2); } } } } } - - protected JenkinsUtils() { - throw new UnsupportedOperationException("Purposefully not implemented"); - } } diff --git a/src/main/java/com/cdancy/jenkins/rest/auth/AuthenticationType.java b/src/main/java/io/github/hmedioni/jenkins/client/auth/AuthenticationType.java similarity index 87% rename from src/main/java/com/cdancy/jenkins/rest/auth/AuthenticationType.java rename to src/main/java/io/github/hmedioni/jenkins/client/auth/AuthenticationType.java index 828f28e..93ac5a1 100644 --- a/src/main/java/com/cdancy/jenkins/rest/auth/AuthenticationType.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/auth/AuthenticationType.java @@ -15,16 +15,16 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.auth; +package io.github.hmedioni.jenkins.client.auth; /** * Supported Authentication Types for Jenkins. */ public enum AuthenticationType { - UsernamePassword("UsernamePassword", "Basic"), - UsernameApiToken("UsernameApiToken", "Basic"), - Anonymous("Anonymous", ""); + USERNAME_PASSWORD("UsernamePassword", "Basic"), + USERNAME_API_TOKEN("UsernameApiToken", "Basic"), + ANONYMOUS("Anonymous", ""); private final String authName; private final String authScheme; diff --git a/src/main/java/io/github/hmedioni/jenkins/client/binders/BindMapToForm.java b/src/main/java/io/github/hmedioni/jenkins/client/binders/BindMapToForm.java new file mode 100644 index 0000000..f716bf1 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/binders/BindMapToForm.java @@ -0,0 +1,48 @@ +/* + * 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. + */ +package io.github.hmedioni.jenkins.client.binders; + + +public class BindMapToForm { + +// @Override +// public R bindToRequest(final R request, final Object properties) { +// +// if (properties == null) { +// return (R) request.toBuilder().build(); +// } +// +// checkArgument(properties instanceof Map, "binder is only valid for Map"); +// Map> props = (Map>) properties; +// +// Builder builder = request.toBuilder(); +// for (Map.Entry> prop : props.entrySet()) { +// if (prop.getKey() != null) { +// String potentialKey = prop.getKey().trim(); +// if (potentialKey.length() > 0) { +// if (prop.getValue() == null) { +// prop.setValue(Lists.newArrayList("")); +// } +// +// builder.addFormParam(potentialKey, prop.getValue().toArray(new String[prop.getValue().size()])); +// } +// } +// } +// +// return (R) builder.build(); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/config/JenkinsProperties.java b/src/main/java/io/github/hmedioni/jenkins/client/config/JenkinsProperties.java new file mode 100644 index 0000000..ccabaac --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/config/JenkinsProperties.java @@ -0,0 +1,42 @@ +package io.github.hmedioni.jenkins.client.config; + +import io.github.hmedioni.jenkins.client.*; +import io.github.hmedioni.jenkins.client.auth.*; +import lombok.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class JenkinsProperties { + + private String url; + private String user; + private String password; + private JenkinsAuthentication jenkinsAuthentication; + + public JenkinsProperties(String url) { + this.url = url; + this.user = null; + this.password = null; + } + + public JenkinsProperties(String url, String user, String password) { + this.url = url; + this.user = user; + this.password = password; + } + + public JenkinsProperties(String url, JenkinsAuthentication jenkinsAuthentication) { + this.url = url; + this.jenkinsAuthentication = jenkinsAuthentication; + } + + public JenkinsAuthentication jenkinsAuthentication() { + if (this.user == null) { + return new JenkinsAuthentication("", AuthenticationType.ANONYMOUS); + } else { + return new JenkinsAuthentication(this.user + ":" + this.password, + AuthenticationType.USERNAME_PASSWORD); + } + } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/common/Value.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/common/Error.java similarity index 79% rename from src/main/java/com/cdancy/jenkins/rest/domain/common/Value.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/common/Error.java index e930b4a..6b14d19 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/common/Value.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/common/Error.java @@ -15,12 +15,19 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.common; +package io.github.hmedioni.jenkins.client.domain.common; -import org.jclouds.javax.annotation.Nullable; -public interface Value { +import lombok.*; + +@Data +@AllArgsConstructor +public class Error { + + public String context; + + public String message; + + public String exceptionName; - @Nullable - public abstract T value(); } diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/common/IntegerResponse.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/common/IntegerResponse.java similarity index 63% rename from src/main/java/com/cdancy/jenkins/rest/domain/common/IntegerResponse.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/common/IntegerResponse.java index a8fe636..5343875 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/common/IntegerResponse.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/common/IntegerResponse.java @@ -15,32 +15,21 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.common; +package io.github.hmedioni.jenkins.client.domain.common; -import java.util.List; - -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; - -import com.cdancy.jenkins.rest.JenkinsUtils; -import com.google.auto.value.AutoValue; +import lombok.*; /** * Integer response to be returned when an endpoint returns * an integer. - * - *

    When the HTTP response code is valid the `value` parameter will + * + *

    When the HTTP response code is valid the `value` parameter will * be set to the integer value while a non-valid response has the `value` set to * null along with any potential `error` objects returned from Jenkins. */ -@AutoValue -public abstract class IntegerResponse implements Value, ErrorsHolder { - - @SerializedNames({ "value", "errors" }) - public static IntegerResponse create(@Nullable final Integer value, - final List errors) { - - return new AutoValue_IntegerResponse(value, - JenkinsUtils.nullToEmpty(errors)); - } +@Data +@NoArgsConstructor +public class IntegerResponse { + + private Integer values; } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/common/RequestStatus.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/common/RequestStatus.java new file mode 100644 index 0000000..90bfe94 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/common/RequestStatus.java @@ -0,0 +1,34 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.common; + +import lombok.*; + +/** + * Generic response to be returned when an endpoint returns + * no content (i.e. 204 response code). + * + *

    When the response code is valid the `value` parameter will + * be set to true while a non-valid response has the `value` set to + * false along with any potential `error` objects returned from Jenkins. + */ +@Data +public class RequestStatus { + + private Boolean value; +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/crumb/Crumb.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/crumb/Crumb.java new file mode 100644 index 0000000..c43b8b4 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/crumb/Crumb.java @@ -0,0 +1,36 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.crumb; + +import com.fasterxml.jackson.annotation.*; +import lombok.*; +import org.springframework.lang.*; + +@Data +@NoArgsConstructor +public class Crumb { + + @Nullable + @JsonProperty("_class") + public String clazz; + @Nullable + public String crumb; + @Nullable + public String crumbRequestField; + +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/crumb/CrumbWrapper.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/crumb/CrumbWrapper.java new file mode 100644 index 0000000..7891317 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/crumb/CrumbWrapper.java @@ -0,0 +1,12 @@ +package io.github.hmedioni.jenkins.client.domain.crumb; + +import lombok.*; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CrumbWrapper { + + private Crumb crumb; + private Boolean aBoolean; +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Action.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Action.java new file mode 100644 index 0000000..8d220a4 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Action.java @@ -0,0 +1,51 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.job; + +import lombok.*; +import org.springframework.lang.*; + +import java.util.*; + +@Data +@NoArgsConstructor +public class Action { + + public List causes; + + public List parameters; + + @Nullable + public String text; + + @Nullable + public String iconPath; + + @Nullable + public String _class; + +// @SerializedNames({"causes", "parameters", "text", "iconPath", "_class"}) +// public static Action create(final List causes, final List parameters, final String text, final String iconPath, final String _class) { +// return new AutoValue_Action( +// causes != null ? ImmutableList.copyOf(causes) : ImmutableList.of, +// parameters != null ? ImmutableList.copyOf(parameters) : ImmutableList.of, +// text, iconPath, _class +// ); +// } +} + diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Artifact.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Artifact.java new file mode 100644 index 0000000..98f788b --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Artifact.java @@ -0,0 +1,39 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.job; + +import lombok.*; +import org.springframework.lang.*; + +@Data +@NoArgsConstructor +public class Artifact { + + @Nullable + public String displayPath; + + public String fileName; + + public String relativePath; + + +// @SerializedNames({ "displayPath", "fileName", "relativePath" }) +// public static Artifact create(String displayPath, String fileName, String relativePath) { +// return new AutoValue_Artifact(displayPath, fileName, relativePath); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/BuildInfo.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/BuildInfo.java new file mode 100644 index 0000000..a5905b5 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/BuildInfo.java @@ -0,0 +1,86 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.job; + +import lombok.*; +import org.springframework.lang.*; + +import java.util.*; + +@Data +@NoArgsConstructor +public class BuildInfo { + + public List artifacts; + + public List actions; + + public boolean building; + + @Nullable + public String description; + + @Nullable + public String displayName; + + public long duration; + + public long estimatedDuration; + + @Nullable + public String fullDisplayName; + + @Nullable + public String id; + + public boolean keepLog; + + public int number; + + public int queueId; + + @Nullable + public String result; + + public long timestamp; + + @Nullable + public String url; + + public List changeSets; + + @Nullable + public String builtOn; + + public List culprits; + +// @SerializedNames({"artifacts", "actions", "building", "description", "displayName", "duration", "estimatedDuration", +// "fullDisplayName", "id", "keepLog", "number", "queueId", "result", "timestamp", "url", "changeSets", "builtOn", "culprits"}) +// public static BuildInfo create(List artifacts, List actions, boolean building, String description, String displayName, +// long duration, long estimatedDuration, String fullDisplayName, String id, boolean keepLog, int number, +// int queueId, String result, long timestamp, String url, List changeSets, String builtOn, List culprits) { +// return new AutoValue_BuildInfo( +// artifacts != null ? ImmutableList.copyOf(artifacts) : ImmutableList.of, +// actions != null ? ImmutableList.copyOf(actions) : ImmutableList.of, +// building, description, displayName, duration, estimatedDuration, fullDisplayName, +// id, keepLog, number, queueId, result, timestamp, url, +// changeSets != null ? ImmutableList.copyOf(changeSets) : ImmutableList.of, +// builtOn, +// culprits != null ? ImmutableList.copyOf(culprits) : ImmutableList.of); +// } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/JobList.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Cause.java similarity index 59% rename from src/main/java/com/cdancy/jenkins/rest/domain/job/JobList.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/job/Cause.java index a5cbedc..5a87bc5 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/JobList.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Cause.java @@ -15,30 +15,29 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.job; +package io.github.hmedioni.jenkins.client.domain.job; -import com.google.auto.value.AutoValue; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; +import lombok.*; +import org.springframework.lang.*; -import java.util.List; - -@AutoValue -public abstract class JobList { +@Data +@NoArgsConstructor +public class Cause { @Nullable - public abstract String clazz(); + public String clazz; - public abstract List jobs(); + public String shortDescription; @Nullable - public abstract String url(); + public String userId; - JobList() { - } + @Nullable + public String userName; - @SerializedNames({"_class", "jobs", "url"}) - public static JobList create(final String clazz, final List jobs, final String url) { - return new AutoValue_JobList(clazz, jobs, url); - } +// +// @SerializedNames({"_class", "shortDescription", "userId", "userName"}) +// public static Cause create(final String clazz, final String shortDescription, final String userId, final String userName) { +// return new AutoValue_Cause(clazz, shortDescription, userId, userName); +// } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/ChangeSet.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/ChangeSet.java new file mode 100644 index 0000000..b3a2449 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/ChangeSet.java @@ -0,0 +1,50 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.job; + +import lombok.*; +import org.springframework.lang.*; + +import java.util.*; + +@Data +@NoArgsConstructor +public class ChangeSet { + + public List affectedPaths; + + public String commitId; + + public long timestamp; + + public Culprit author; + + @Nullable + public String authorEmail; + + @Nullable + public String comment; + + +// @SerializedNames({ "affectedPaths", "commitId", "timestamp", "author", "authorEmail", "comment" }) +// public static ChangeSet create(List affectedPaths, String commitId, long timestamp, Culprit author, String authorEmail, String comment) { +// return new AutoValue_ChangeSet( +// affectedPaths != null ? ImmutableList.copyOf(affectedPaths) : ImmutableList. of, +// commitId, timestamp, author, authorEmail, comment); +// } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/ProgressiveText.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/ChangeSetList.java similarity index 60% rename from src/main/java/com/cdancy/jenkins/rest/domain/job/ProgressiveText.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/job/ChangeSetList.java index 8e31fdb..538b918 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/ProgressiveText.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/ChangeSetList.java @@ -15,26 +15,27 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.job; +package io.github.hmedioni.jenkins.client.domain.job; -import org.jclouds.json.SerializedNames; +import lombok.*; +import org.springframework.lang.*; -import com.google.auto.value.AutoValue; +import java.util.*; -@AutoValue -public abstract class ProgressiveText { +@Data +@NoArgsConstructor +public class ChangeSetList { - public abstract String text(); + public List items; - public abstract int size(); + @Nullable + public String kind; - public abstract boolean hasMoreData(); - ProgressiveText() { - } - - @SerializedNames({ "text", "size", "hasMoreData" }) - public static ProgressiveText create(String text, int size, boolean hasMoreData) { - return new AutoValue_ProgressiveText(text, size, hasMoreData); - } +// @SerializedNames({ "items", "kind" }) +// public static ChangeSetList create(List items, String kind) { +// return new AutoValue_ChangeSetList( +// items != null ? ImmutableList.copyOf(items) : ImmutableList. of, +// kind); +// } } diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/queue/Executable.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Culprit.java similarity index 65% rename from src/main/java/com/cdancy/jenkins/rest/domain/queue/Executable.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/job/Culprit.java index 0fca911..f1e4fcd 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/queue/Executable.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Culprit.java @@ -15,24 +15,22 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.queue; +package io.github.hmedioni.jenkins.client.domain.job; -import org.jclouds.json.SerializedNames; -import com.google.auto.value.AutoValue; +import lombok.*; -@AutoValue -public abstract class Executable { - public abstract Integer number(); +@Data +public class Culprit { - public abstract String url(); + public String absoluteUrl; - Executable() { - } + public String fullName; - @SerializedNames({ "number", "url" }) - public static Executable create(Integer number, String url) { - return new AutoValue_Executable(number, url); - } + +// @SerializedNames({"absoluteUrl", "fullName"}) +// public static Culprit create(String absoluteUrl, String fullName) { +// return new AutoValue_Culprit(absoluteUrl, fullName); +// } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Job.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Job.java new file mode 100644 index 0000000..78bfd8b --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Job.java @@ -0,0 +1,25 @@ +package io.github.hmedioni.jenkins.client.domain.job; + + +import lombok.*; +import org.springframework.lang.*; + +@Data +public class Job { + + @Nullable + public String clazz; + + public String name; + + public String url; + + @Nullable + public String color; + + +// @SerializedNames({"_class", "name", "url", "color"}) +// public static Job create(final String clazz, final String name, final String url, final String color) { +// return new AutoValue_Job(clazz, name, url, color); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/JobInfo.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/JobInfo.java new file mode 100644 index 0000000..9d59ec1 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/JobInfo.java @@ -0,0 +1,100 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.job; + + +import io.github.hmedioni.jenkins.client.domain.queue.*; +import lombok.*; +import org.springframework.lang.*; + +import java.util.*; + +@Data +public class JobInfo { + + @Nullable + public String description; + + @Nullable + public String displayName; + + @Nullable + public String displayNameOrNull; + + public String name; + + public String url; + + public boolean buildable; + + public List builds; + + @Nullable + public String color; + + @Nullable + public BuildInfo firstBuild; + + public boolean inQueue; + + public boolean keepDependencies; + + @Nullable + public BuildInfo lastBuild; + + @Nullable + public BuildInfo lastCompleteBuild; + + @Nullable + public BuildInfo lastFailedBuild; + + @Nullable + public BuildInfo lastStableBuild; + + @Nullable + public BuildInfo lastSuccessfulBuild; + + @Nullable + public BuildInfo lastUnstableBuild; + + @Nullable + public BuildInfo lastUnsuccessfulBuild; + + public int nextBuildNumber; + + @Nullable + public QueueItem queueItem; + + public boolean concurrentBuild; + + +// @SerializedNames({"description", "displayName", "displayNameOrNull", "name", "url", "buildable", "builds", "color", +// "firstBuild", "inQueue", "keepDependencies", "lastBuild", "lastCompleteBuild", "lastFailedBuild", +// "lastStableBuild", "lastSuccessfulBuild", "lastUnstableBuild", "lastUnsuccessfulBuild", "nextBuildNumber", +// "queueItem", "concurrentBuild"}) +// public static JobInfo create(String description, String displayName, String displayNameOrNull, String name, +// String url, boolean buildable, List builds, String color, BuildInfo firstBuild, boolean inQueue, +// boolean keepDependencies, BuildInfo lastBuild, BuildInfo lastCompleteBuild, BuildInfo lastFailedBuild, +// BuildInfo lastStableBuild, BuildInfo lastSuccessfulBuild, BuildInfo lastUnstableBuild, BuildInfo lastUnsuccessfulBuild, +// int nextBuildNumber, QueueItem queueItem, boolean concurrentBuild) { +// return new AutoValue_JobInfo(description, displayName, displayNameOrNull, name, url, buildable, +// builds != null ? ImmutableList.copyOf(builds) : ImmutableList.of, color, firstBuild, inQueue, +// keepDependencies, lastBuild, lastCompleteBuild, lastFailedBuild, lastStableBuild, lastSuccessfulBuild, +// lastUnstableBuild, lastUnsuccessfulBuild, nextBuildNumber, queueItem, concurrentBuild); +// } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/queue/Task.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/JobList.java similarity index 63% rename from src/main/java/com/cdancy/jenkins/rest/domain/queue/Task.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/job/JobList.java index a157a45..b919f81 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/queue/Task.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/JobList.java @@ -15,27 +15,28 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.queue; +package io.github.hmedioni.jenkins.client.domain.job; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; -import com.google.auto.value.AutoValue; +import lombok.*; +import org.springframework.lang.*; -@AutoValue -public abstract class Task { +import java.util.*; - @Nullable - public abstract String name(); +@Data +public class JobList { - @Nullable - public abstract String url(); + @Nullable + public String clazz; - Task() { - } + public List jobs; - @SerializedNames({ "name", "url" }) - public static Task create(String name, String url) { - return new AutoValue_Task(name, url); - } + @Nullable + public String url; + + +// @SerializedNames({"_class", "jobs", "url"}) +// public static JobList create(final String clazz, final List jobs, final String url) { +// return new AutoValue_JobList(clazz, jobs, url); +// } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Parameter.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Parameter.java new file mode 100644 index 0000000..6677734 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Parameter.java @@ -0,0 +1,40 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.job; + + +import lombok.*; +import org.springframework.lang.*; + +@Data +public class Parameter { + + @Nullable + public String clazz; + + public String name; + + @Nullable + public String value; + + +// @SerializedNames({"_class", "name", "value"}) +// public static Parameter create(final String clazz, final String name, final String value) { +// return new AutoValue_Parameter(clazz, name, value); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/PipelineNode.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/PipelineNode.java new file mode 100644 index 0000000..6ceb928 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/PipelineNode.java @@ -0,0 +1,26 @@ +package io.github.hmedioni.jenkins.client.domain.job; + + +import lombok.*; + +import java.util.*; + +@Data +public class PipelineNode { + + public String name; + + public String status; + + public long startTimeMillis; + + public long durationTimeMillis; + + public List stageFlowNodes; + + +// @SerializedNames({"name", "status", "startTimeMillis", "durationTimeMillis", "stageFlowNodes"}) +// public static PipelineNode create(String name, String status, long startTimeMillis, long durationTimeMillis, List stageFlowNodes) { +// return new AutoValue_PipelineNode(name, status, startTimeMillis, durationTimeMillis, stageFlowNodes); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/PipelineNodeLog.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/PipelineNodeLog.java new file mode 100644 index 0000000..b5592e8 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/PipelineNodeLog.java @@ -0,0 +1,26 @@ +package io.github.hmedioni.jenkins.client.domain.job; + + +import lombok.*; + + +@Data +public class PipelineNodeLog { + + public String nodeId; + + public String nodeStatus; + + public int length; + + public boolean hasMore; + + public String text; + + public String consoleUrl; + +// @SerializedNames({"nodeId", "nodeStatus", "length", "hasMore", "text", "consoleUrl"}) +// public static PipelineNodeLog create(String nodeId, String nodeStatus, int length, boolean hasMore, String text, String consoleUrl) { +// return new AutoValue_PipelineNodeLog(nodeId, nodeStatus, length, hasMore, text, consoleUrl); +// } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/Culprit.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/ProgressiveText.java similarity index 64% rename from src/main/java/com/cdancy/jenkins/rest/domain/job/Culprit.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/job/ProgressiveText.java index d88f89d..a2bd388 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/Culprit.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/ProgressiveText.java @@ -15,24 +15,24 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.job; +package io.github.hmedioni.jenkins.client.domain.job; -import org.jclouds.json.SerializedNames; -import com.google.auto.value.AutoValue; +import lombok.*; -@AutoValue -public abstract class Culprit { - public abstract String absoluteUrl(); +@Data +public class ProgressiveText { - public abstract String fullName(); + public String text; - Culprit() { - } + public int size; - @SerializedNames({ "absoluteUrl", "fullName" }) - public static Culprit create(String absoluteUrl, String fullName) { - return new AutoValue_Culprit(absoluteUrl, fullName); - } + public boolean hasMoreData; + + +// @SerializedNames({"text", "size", "hasMoreData"}) +// public static ProgressiveText create(String text, int size, boolean hasMoreData) { +// return new AutoValue_ProgressiveText(text, size, hasMoreData); +// } } diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/Cause.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Stage.java similarity index 52% rename from src/main/java/com/cdancy/jenkins/rest/domain/job/Cause.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/job/Stage.java index 121d6a3..709742e 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/Cause.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Stage.java @@ -15,31 +15,31 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.job; +package io.github.hmedioni.jenkins.client.domain.job; -import com.google.auto.value.AutoValue; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; -@AutoValue -public abstract class Cause { +import lombok.*; - @Nullable - public abstract String clazz(); - public abstract String shortDescription(); +@Data +public class Stage { + public String id; - @Nullable - public abstract String userId(); + public String name; - @Nullable - public abstract String userName(); + public String status; - Cause() { - } + public long startTimeMillis; - @SerializedNames({"_class", "shortDescription", "userId", "userName"}) - public static Cause create(final String clazz, final String shortDescription, final String userId, final String userName) { - return new AutoValue_Cause(clazz, shortDescription, userId, userName); - } + public long endTimeMillis; + + public long pauseDurationMillis; + + public long durationMillis; + + +// @SerializedNames({"id", "name", "status", "startTimeMillis", "endTimeMillis", "pauseDurationMillis", "durationMillis"}) +// public static Stage create(String id, String name, String status, long startTimeMillis, long endTimeMillis, long pauseDurationMillis, long durationMillis) { +// return new AutoValue_Stage(id, name, status, startTimeMillis, endTimeMillis, pauseDurationMillis, durationMillis); +// } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/job/StageFlowNode.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/StageFlowNode.java new file mode 100644 index 0000000..6409a9b --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/StageFlowNode.java @@ -0,0 +1,43 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.job; + + +import lombok.*; + +import java.util.*; + +@Data +public class StageFlowNode { + + public String name; + + public String status; + + public long startTimeMillis; + + public long durationTimeMillis; + + public List parentNodes; + + +// @SerializedNames({"name", "status", "startTimeMillis", "durationTimeMillis", "parentNodes"}) +// public static StageFlowNode create(String name, String status, long startTimeMillis, long durationTimeMillis, List parentNodes) { +// return new AutoValue_StageFlowNode(name, status, startTimeMillis, durationTimeMillis, parentNodes); +// } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/Artifact.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Workflow.java similarity index 57% rename from src/main/java/com/cdancy/jenkins/rest/domain/job/Artifact.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/job/Workflow.java index acaedd6..70bafa0 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/Artifact.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/job/Workflow.java @@ -15,28 +15,29 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.job; +package io.github.hmedioni.jenkins.client.domain.job; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; -import com.google.auto.value.AutoValue; +import lombok.*; -@AutoValue -public abstract class Artifact { +import java.util.*; - @Nullable - public abstract String displayPath(); +@Data +public class Workflow { - public abstract String fileName(); + public String name; - public abstract String relativePath(); + public String status; - Artifact() { - } + public long startTimeMillis; - @SerializedNames({ "displayPath", "fileName", "relativePath" }) - public static Artifact create(String displayPath, String fileName, String relativePath) { - return new AutoValue_Artifact(displayPath, fileName, relativePath); - } + public long durationTimeMillis; + + public List stages; + + +// @SerializedNames({"name", "status", "startTimeMillis", "durationTimeMillis", "stages"}) +// public static Workflow create(String name, String status, long startTimeMillis, long durationTimeMillis, List stages) { +// return new AutoValue_Workflow(name, status, startTimeMillis, durationTimeMillis, stages); +// } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/plugins/Plugin.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/plugins/Plugin.java new file mode 100644 index 0000000..5e0bdc3 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/plugins/Plugin.java @@ -0,0 +1,86 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.plugins; + + +import lombok.*; +import org.springframework.lang.*; + +@Data +public class Plugin { + + @Nullable + public Boolean active; + + @Nullable + public String backupVersion; + + @Nullable + public Boolean bundled; + + @Nullable + public Boolean deleted; + + @Nullable + public Boolean downgradable; + + @Nullable + public Boolean enabled; + + @Nullable + public Boolean hasUpdate; + + @Nullable + public String longName; + + @Nullable + public Boolean pinned; + + @Nullable + public String requiredCoreVersion; + + @Nullable + public String shortName; + + @Nullable + public String supportsDynamicLoad; + + @Nullable + public String url; + + @Nullable + public String version; + + +// @SerializedNames({"active", "backupVersion", "bundled", +// "deleted", "downgradable", "enabled", +// "hasUpdate", "longName", "pinned", +// "requiredCoreVersion", "shortName", "supportsDynamicLoad", +// "url", "version"}) +// public static Plugin create(Boolean active, String backupVersion, Boolean bundled, +// Boolean deleted, Boolean downgradable, Boolean enabled, +// Boolean hasUpdate, String longName, Boolean pinned, +// String requiredCoreVersion, String shortName, String supportsDynamicLoad, +// String url, String version) { +// return new AutoValue_Plugin(active, backupVersion, bundled, +// deleted, downgradable, enabled, +// hasUpdate, longName, pinned, +// requiredCoreVersion, shortName, supportsDynamicLoad, +// url, version); +// } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/job/Parameter.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/plugins/Plugins.java similarity index 57% rename from src/main/java/com/cdancy/jenkins/rest/domain/job/Parameter.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/plugins/Plugins.java index 4edd0ab..c42ef60 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/job/Parameter.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/plugins/Plugins.java @@ -15,28 +15,28 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.job; +package io.github.hmedioni.jenkins.client.domain.plugins; -import com.google.auto.value.AutoValue; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; -@AutoValue -public abstract class Parameter { +import lombok.*; +import org.springframework.lang.*; - @Nullable - public abstract String clazz(); +import java.util.*; - public abstract String name(); +@Data +public class Plugins { @Nullable - public abstract String value(); - - Parameter() { - } - - @SerializedNames({"_class", "name", "value"}) - public static Parameter create(final String clazz, final String name, final String value) { - return new AutoValue_Parameter(clazz, name, value); - } + public String clazz; + + public List plugins; + +// @SerializedNames({"_class", "plugins", "errors"}) +// public static Plugins create(final String clazz, +// final List plugins, +// final List errors) { +// return new AutoValue_Plugins(JenkinsUtils.nullToEmpty(errors), +// clazz, +// JenkinsUtils.nullToEmpty(plugins)); +// } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/Executable.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/Executable.java new file mode 100644 index 0000000..d06dd0e --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/Executable.java @@ -0,0 +1,35 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.queue; + + +import lombok.*; + +@Data +public class Executable { + + public Integer number; + + public String url; + + +// @SerializedNames({"number", "url"}) +// public static Executable create(Integer number, String url) { +// return new AutoValue_Executable(number, url); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/QueueItem.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/QueueItem.java new file mode 100644 index 0000000..d8e28d4 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/QueueItem.java @@ -0,0 +1,90 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.queue; + +import lombok.*; +import org.springframework.lang.*; + +import java.util.*; + +@Data +public class QueueItem { + + public boolean blocked; + + public boolean buildable; + + public int id; + + public long inQueueSince; + + public Map params; + + public boolean stuck; + + public Task task; + + public String url; + + @Nullable + public String why; + + // https://javadoc.jenkins.io/hudson/model/Queue.NotWaitingItem.html + /** + * When did this job exit the Queue.waitingList phase? + * For a Queue.NotWaitingItem + * + * @return The time expressed in milliseconds after January 1, 1970, 0:00:00 GMT. + */ + public long buildableStartMilliseconds; + + public boolean cancelled; + + @Nullable + public Executable executable; + + // https://javadoc.jenkins.io/hudson/model/Queue.WaitingItem.html + /** + * This item can be run after this time. + * For a Queue.WaitingItem + * + * @return The time expressed in milliseconds after January 1, 1970, 0:00:00 GMT. + */ + @Nullable + public Long timestamp; + + +// @SerializedNames({"blocked", "buildable", "id", "inQueueSince", "params", "stuck", "task", "url", "why", +// "buildableStartMilliseconds", "cancelled", "executable", "timestamp"}) +// public static QueueItem create(boolean blocked, boolean buildable, int id, long inQueueSince, String params, +// boolean stuck, Task task, String url, String why, long buildableStartMilliseconds, +// boolean cancelled, Executable executable, Long timestamp) { +// Map parameters = Maps.newHashMap; +// if (params != null) { +// params = params.trim; +// if (params.length > 0) { +// for (String keyValue : params.split("\n")) { +// String[] pair = keyValue.split("="); +// parameters.put(pair[0], pair.length > 1 ? pair[1] : ""); +// } +// } +// } +// return new AutoValue_QueueItem(blocked, buildable, id, inQueueSince, parameters, stuck, task, url, why, +// buildableStartMilliseconds, cancelled, executable, timestamp); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/Task.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/Task.java new file mode 100644 index 0000000..d7047ee --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/queue/Task.java @@ -0,0 +1,37 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.queue; + +import lombok.*; +import org.springframework.lang.*; + +@Data +public class Task { + + @Nullable + public String name; + + @Nullable + public String url; + +// +// @SerializedNames({"name", "url"}) +// public static Task create(String name, String url) { +// return new AutoValue_Task(name, url); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/statistics/OverallLoad.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/statistics/OverallLoad.java new file mode 100644 index 0000000..f0348a0 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/statistics/OverallLoad.java @@ -0,0 +1,68 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.statistics; + +import lombok.*; +import org.springframework.lang.*; + +import java.util.*; + +@Data +public class OverallLoad { + + @Nullable + public Map availableExecutors; + + @Nullable + public Map busyExecutors; + + @Nullable + public Map connectingExecutors; + + @Nullable + public Map definedExecutors; + + @Nullable + public Map idleExecutors; + + @Nullable + public Map onlineExecutors; + + @Nullable + public Map queueLength; + + @Nullable + public Map totalExecutors; + + @Nullable + public Map totalQueueLength; + + +// @SerializedNames({"availableExecutors", "busyExecutors", "connectingExecutors", "definedExecutors", "idleExecutors", +// "onlineExecutors", "queueLength", "totalExecutors", "totalQueueLength"}) +// public static OverallLoad create(Map availableExecutors, Map busyExecutors, +// Map connectingExecutors, Map definedExecutors, +// Map idleExecutors, Map onlineExecutors, Map queueLength, +// Map totalExecutors, Map totalQueueLength) { +// return new AutoValue_OverallLoad(availableExecutors, busyExecutors, +// connectingExecutors, definedExecutors, +// idleExecutors, onlineExecutors, +// queueLength, totalExecutors, +// totalQueueLength); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/system/SystemInfo.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/system/SystemInfo.java new file mode 100644 index 0000000..ed86c46 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/system/SystemInfo.java @@ -0,0 +1,49 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.domain.system; + +import lombok.*; +import org.springframework.lang.*; + +@Data +public class SystemInfo { + + public String hudsonVersion; + + public String jenkinsVersion; + + public String jenkinsSession; + + public String instanceIdentity; + + @Nullable + public String sshEndpoint; + + public String server; + + +// @SerializedNames({"hudsonVersion", "jenkinsVersion", "jenkinsSession", +// "instanceIdentity", "sshEndpoint", "server", "errors"}) +// public static SystemInfo create(String hudsonVersion, String jenkinsVersion, String jenkinsSession, +// String instanceIdentity, +// String sshEndpoint, String server, final List errors) { +// return new AutoValue_SystemInfo(JenkinsUtils.nullToEmpty(errors), +// hudsonVersion, jenkinsVersion, jenkinsSession, +// instanceIdentity, sshEndpoint, server); +// } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/user/ApiToken.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/user/ApiToken.java similarity index 64% rename from src/main/java/com/cdancy/jenkins/rest/domain/user/ApiToken.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/user/ApiToken.java index b6bfe01..e950ce1 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/user/ApiToken.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/user/ApiToken.java @@ -14,23 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.cdancy.jenkins.rest.domain.user; +package io.github.hmedioni.jenkins.client.domain.user; -import com.google.auto.value.AutoValue; -import org.jclouds.json.SerializedNames; +import lombok.*; -@AutoValue -public abstract class ApiToken { +@Data +public class ApiToken { - public abstract String status(); + public String status; - public abstract ApiTokenData data(); + public ApiTokenData data; - ApiToken() { - } - @SerializedNames({"status", "data"}) - public static ApiToken create(final String status, final ApiTokenData data) { - return new AutoValue_ApiToken(status, data); - } +// @SerializedNames({"status", "data"}) +// public static ApiToken create(final String status, final ApiTokenData data) { +// return new AutoValue_ApiToken(status, data); +// } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/user/ApiTokenData.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/user/ApiTokenData.java new file mode 100644 index 0000000..cab8bcf --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/user/ApiTokenData.java @@ -0,0 +1,34 @@ +/* + * 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. + */ +package io.github.hmedioni.jenkins.client.domain.user; + + +import lombok.*; + +@Data +public class ApiTokenData { + + public String tokenName; + public String tokenUuid; + public String tokenValue; + + +// @SerializedNames({"tokenName", "tokenUuid", "tokenValue"}) +// public static ApiTokenData create(final String tokenName, final String tokenUuid, final String tokenValue) { +// return new AutoValue_ApiTokenData(tokenName, tokenUuid, tokenValue); +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/domain/user/Property.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/user/Property.java new file mode 100644 index 0000000..e946c86 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/user/Property.java @@ -0,0 +1,17 @@ +package io.github.hmedioni.jenkins.client.domain.user; + + +import lombok.*; + + +@Data +public class Property { + + public String clazz; + + +// @SerializedNames({"_class"}) +// public static Property create(final String clazz) { +// return new AutoValue_Property(clazz); +// } +} diff --git a/src/main/java/com/cdancy/jenkins/rest/domain/common/Error.java b/src/main/java/io/github/hmedioni/jenkins/client/domain/user/User.java similarity index 54% rename from src/main/java/com/cdancy/jenkins/rest/domain/common/Error.java rename to src/main/java/io/github/hmedioni/jenkins/client/domain/user/User.java index 41db5a7..5bf545e 100644 --- a/src/main/java/com/cdancy/jenkins/rest/domain/common/Error.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/domain/user/User.java @@ -14,35 +14,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package io.github.hmedioni.jenkins.client.domain.user; -package com.cdancy.jenkins.rest.domain.common; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.json.SerializedNames; +import lombok.*; +import org.springframework.lang.*; -import com.google.auto.value.AutoValue; +@Data +public class User { -@AutoValue -public abstract class Error { + public String absoluteUrl; @Nullable - public abstract String context(); + public String description; - @Nullable - public abstract String message(); - - public abstract String exceptionName(); - - Error() { - } - - @SerializedNames({ "context", "message", "exceptionName" }) - public static Error create(final String context, - final String message, - final String exceptionName) { - - return new AutoValue_Error(context, - message, - exceptionName); - } + public String fullName; + + public String id; + + // TODO: Find a way to support properties, which is a list of different extensions of a base class + // public List properties; + + +// @SerializedNames({"absoluteUrl", "description", "fullName", "id"}) +// public static User create(final String absoluteUrl, final String description, final String fullName, final String id) { +// return new AutoValue_User(absoluteUrl, description, fullName, id); +// } } diff --git a/src/main/java/com/cdancy/jenkins/rest/exception/ForbiddenException.java b/src/main/java/io/github/hmedioni/jenkins/client/exception/ForbiddenException.java similarity index 93% rename from src/main/java/com/cdancy/jenkins/rest/exception/ForbiddenException.java rename to src/main/java/io/github/hmedioni/jenkins/client/exception/ForbiddenException.java index ce706c0..f0552ce 100644 --- a/src/main/java/com/cdancy/jenkins/rest/exception/ForbiddenException.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/exception/ForbiddenException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.exception; +package io.github.hmedioni.jenkins.client.exception; /** * Thrown when an action has breached the licensed user limit of the server, or @@ -26,6 +26,6 @@ public class ForbiddenException extends RuntimeException { private static final long serialVersionUID = 1L; public ForbiddenException(final String arg0) { - super(arg0); + super(arg0); } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/exception/JenkinsAppException.java b/src/main/java/io/github/hmedioni/jenkins/client/exception/JenkinsAppException.java new file mode 100644 index 0000000..0513de2 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/exception/JenkinsAppException.java @@ -0,0 +1,40 @@ +package io.github.hmedioni.jenkins.client.exception; + +import org.springframework.http.*; + +import java.io.*; +import java.util.*; + +/** + * Thrown when an action has breached the licensed user limit of the server, or + * degrading the authenticated user's permission level. + */ +public class JenkinsAppException extends RuntimeException { + + @Serial + private static final long serialVersionUID = -1L; + private final List errors; + private final HttpStatusCode httpStatusCode; + + + + public JenkinsAppException(final String responseBody, final List errors, HttpStatusCode httpStatusCode) { + super(responseBody); + this.errors = errors; + this.httpStatusCode = httpStatusCode; + } + + public JenkinsAppException(final String responseBody, final List errors, HttpStatusCode httpStatusCode, final Throwable arg1) { + super(responseBody, arg1); + this.errors = errors; + this.httpStatusCode = httpStatusCode; + } + + public List errors() { + return errors; + } + + public HttpStatusCode code() { + return httpStatusCode; + } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/exception/JenkinsError.java b/src/main/java/io/github/hmedioni/jenkins/client/exception/JenkinsError.java new file mode 100644 index 0000000..bce08b5 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/exception/JenkinsError.java @@ -0,0 +1,31 @@ +package io.github.hmedioni.jenkins.client.exception; + +import lombok.*; +import org.springframework.lang.*; + +import java.io.*; +import java.util.*; + + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class JenkinsError implements Serializable { + + @Serial + private static final long serialVersionUID = -1L; + + + @Nullable + private String context; + + @Nullable + private String message; + + @Nullable + private String exceptionName; + + private boolean conflicted; + + +} diff --git a/src/main/java/com/cdancy/jenkins/rest/exception/MethodNotAllowedException.java b/src/main/java/io/github/hmedioni/jenkins/client/exception/MethodNotAllowedException.java similarity index 93% rename from src/main/java/com/cdancy/jenkins/rest/exception/MethodNotAllowedException.java rename to src/main/java/io/github/hmedioni/jenkins/client/exception/MethodNotAllowedException.java index 10803fd..f53a3b9 100644 --- a/src/main/java/com/cdancy/jenkins/rest/exception/MethodNotAllowedException.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/exception/MethodNotAllowedException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.exception; +package io.github.hmedioni.jenkins.client.exception; /** * Thrown when a method was used that is not supported by this endpoint. @@ -25,6 +25,6 @@ public class MethodNotAllowedException extends RuntimeException { private static final long serialVersionUID = 1L; public MethodNotAllowedException(final String arg0) { - super(arg0); + super(arg0); } } diff --git a/src/main/java/com/cdancy/jenkins/rest/exception/RedirectTo404Exception.java b/src/main/java/io/github/hmedioni/jenkins/client/exception/RedirectTo404Exception.java similarity index 93% rename from src/main/java/com/cdancy/jenkins/rest/exception/RedirectTo404Exception.java rename to src/main/java/io/github/hmedioni/jenkins/client/exception/RedirectTo404Exception.java index 116c53b..5c49172 100644 --- a/src/main/java/com/cdancy/jenkins/rest/exception/RedirectTo404Exception.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/exception/RedirectTo404Exception.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.exception; +package io.github.hmedioni.jenkins.client.exception; /** * Thrown when an action has breached the licensed user limit of the server, or @@ -26,6 +26,6 @@ public class RedirectTo404Exception extends RuntimeException { private static final long serialVersionUID = 1L; public RedirectTo404Exception(final String arg0) { - super(arg0); + super(arg0); } } diff --git a/src/main/java/com/cdancy/jenkins/rest/exception/UndetectableIdentityException.java b/src/main/java/io/github/hmedioni/jenkins/client/exception/UndetectableIdentityException.java similarity index 94% rename from src/main/java/com/cdancy/jenkins/rest/exception/UndetectableIdentityException.java rename to src/main/java/io/github/hmedioni/jenkins/client/exception/UndetectableIdentityException.java index ae73e9a..bbe0bc5 100644 --- a/src/main/java/com/cdancy/jenkins/rest/exception/UndetectableIdentityException.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/exception/UndetectableIdentityException.java @@ -15,11 +15,11 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.exception; +package io.github.hmedioni.jenkins.client.exception; /** * The credential being passed cannot be processed. - * + *

    * A valid credential is either *

      *
    1. a colon separated identity and password or token (tuple of )identity:password or identity:token); or
    2. @@ -27,12 +27,11 @@ *
    * When the credential does not contain a colon, an attempt is made at decoding it to extract the identity. * When this fails, this exception is thrown. - * */ public class UndetectableIdentityException extends RuntimeException { private static final long serialVersionUID = 1L; public UndetectableIdentityException(final String arg0) { - super(arg0); + super(arg0); } } diff --git a/src/main/java/com/cdancy/jenkins/rest/exception/UnsupportedMediaTypeException.java b/src/main/java/io/github/hmedioni/jenkins/client/exception/UnsupportedMediaTypeException.java similarity index 94% rename from src/main/java/com/cdancy/jenkins/rest/exception/UnsupportedMediaTypeException.java rename to src/main/java/io/github/hmedioni/jenkins/client/exception/UnsupportedMediaTypeException.java index c82e8b0..149ac1c 100644 --- a/src/main/java/com/cdancy/jenkins/rest/exception/UnsupportedMediaTypeException.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/exception/UnsupportedMediaTypeException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.exception; +package io.github.hmedioni.jenkins.client.exception; /** * The request entity has a Content-Type that the server does not support. @@ -29,6 +29,6 @@ public class UnsupportedMediaTypeException extends RuntimeException { private static final long serialVersionUID = 1L; public UnsupportedMediaTypeException(final String arg0) { - super(arg0); + super(arg0); } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/fallbacks/JenkinsFallbacks.java b/src/main/java/io/github/hmedioni/jenkins/client/fallbacks/JenkinsFallbacks.java new file mode 100644 index 0000000..0f24705 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/fallbacks/JenkinsFallbacks.java @@ -0,0 +1,150 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.fallbacks; +// +// +//import io.github.hmedioni.jenkins.client.domain.common.Error; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.crumb.*; +//import io.github.hmedioni.jenkins.client.domain.plugins.*; +//import io.github.hmedioni.jenkins.client.domain.system.*; +// +//import java.util.*; +// +// +//public final class JenkinsFallbacks { +// +// public static SystemInfo createSystemInfoFromErrors(final List errors) { +// final String illegalValue = "-1"; +// return SystemInfo.create(illegalValue, illegalValue, illegalValue, +// illegalValue, illegalValue, illegalValue, errors); +// } +// +// /** +// * Parse list of Error's from generic Exception. +// * +// * @param output Exception containing error data +// * @return List of culled Error's +// */ +// public static List getErrors(final Exception output) { +// final Error error = Error.create(null, output.getMessage(), +// output.getClass().getName()); +// return Lists.newArrayList(error); +// } +// +// /** +// * Parse list of Error's from output. +// * +// * @param output Throwable containing error data +// * @return List of culled Error's +// */ +// public static List getErrors(final Throwable output) { +// +// final List errors = Lists.newArrayList(); +// +// String context = null; +// String message = output.getMessage(); +// final String[] messageParts = output.getMessage().split("->"); +// switch (messageParts.length) { +// case 1: +// message = messageParts[0].trim(); +// break; +// case 3: +// context = messageParts[0].trim(); +// message = messageParts[2].trim(); +// break; +// } +// +// final Error error = Error.create(context, message, output.getClass().getCanonicalName()); +// errors.add(error); +// +// return errors; +// } +// +// public static final class SystemInfoOnError implements Fallback { +// @Override +// public Object createOrPropagate(final Throwable throwable) { +// checkNotNull(throwable, "throwable"); +// return createSystemInfoFromErrors(getErrors(throwable)); +// } +// } +// +// public static final class RequestStatusOnError implements Fallback { +// @Override +// public Object createOrPropagate(final Throwable throwable) { +// checkNotNull(throwable, "throwable"); +// try { +// return RequestStatus.create(false, getErrors(throwable)); +// } catch (JsonSyntaxException e) { +// return RequestStatus.create(false, getErrors(e)); +// } +// } +// } +// +// public static final class IntegerResponseOnError implements Fallback { +// @Override +// public Object createOrPropagate(final Throwable throwable) { +// checkNotNull(throwable, "throwable"); +// try { +// return IntegerResponse.create(null, getErrors(throwable)); +// } catch (JsonSyntaxException e) { +// return IntegerResponse.create(null, getErrors(e)); +// } +// } +// } +// +// public static final class CrumbOnError implements Fallback { +// @Override +// public Object createOrPropagate(final Throwable throwable) { +// checkNotNull(throwable, "throwable"); +// try { +// return Crumb.create(null, getErrors(throwable)); +// } catch (JsonSyntaxException e) { +// return Crumb.create(null, getErrors(e)); +// } +// } +// } +// +// public static final class PluginsOnError implements Fallback { +// @Override +// public Object createOrPropagate(final Throwable throwable) { +// checkNotNull(throwable, "throwable"); +// try { +// return Plugins.create(null, null, getErrors(throwable)); +// } catch (JsonSyntaxException e) { +// return Plugins.create(null, null, getErrors(e)); +// } +// } +// } +// +// // fix/hack for Jenkins jira issue: JENKINS-21311 +// public static final class JENKINS_21311 implements Fallback { +// @Override +// public Object createOrPropagate(final Throwable throwable) { +// checkNotNull(throwable, "throwable"); +// try { +// if (throwable.getClass() == ResourceNotFoundException.class) { +// return RequestStatus.create(true, null); +// } else { +// return RequestStatus.create(false, getErrors(throwable)); +// } +// } catch (JsonSyntaxException e) { +// return RequestStatus.create(false, getErrors(e)); +// } +// } +// } +//} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApi.java b/src/main/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApi.java new file mode 100644 index 0000000..7a70772 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApi.java @@ -0,0 +1,47 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.features; + +import io.github.hmedioni.jenkins.client.domain.common.*; +import org.springframework.http.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.service.annotation.*; + + +//@RequestFilters(JenkinsAuthenticationFilter.class) +@HttpExchange(url = "/configuration-as-code", accept = MediaType.APPLICATION_JSON_VALUE, contentType = MediaType.APPLICATION_JSON_VALUE) +public interface ConfigurationAsCodeApi { + + // // @Named("casc:check") +// @Path("/check") +// @Fallback(JenkinsFallbacks.RequestStatusOnError.class) +// @ResponseParser(RequestStatusParser.class) +// @Payload("{cascYml}")cascYml +// @PostExchange + @PostExchange("/check") + ResponseEntity check(@RequestBody String cascYml); + + // // @Named("casc:apply") +// @Path("/apply") +// @Fallback(JenkinsFallbacks.RequestStatusOnError.class) +// @ResponseParser(RequestStatusParser.class) +// @Payload("{cascYml}") +// @PostExchange + @PostExchange("/apply") + ResponseEntity apply(@RequestBody String cascYml); +} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/CrumbIssuerApiLiveTest.java b/src/main/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApi.java similarity index 52% rename from src/test/java/com/cdancy/jenkins/rest/features/CrumbIssuerApiLiveTest.java rename to src/main/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApi.java index ecf1a00..0b2cf9e 100644 --- a/src/test/java/com/cdancy/jenkins/rest/features/CrumbIssuerApiLiveTest.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApi.java @@ -14,28 +14,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.cdancy.jenkins.rest.features; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; +package io.github.hmedioni.jenkins.client.features; -import org.testng.annotations.Test; +import io.github.hmedioni.jenkins.client.domain.crumb.*; +import org.springframework.http.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.service.annotation.*; -import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest; -import com.cdancy.jenkins.rest.domain.crumb.Crumb; +//@RequestFilters(JenkinsNoCrumbAuthenticationFilter.class) +@HttpExchange(url = "/crumbIssuer/api/json", accept = MediaType.APPLICATION_JSON_VALUE, contentType = MediaType.APPLICATION_JSON_VALUE) +public interface CrumbIssuerApi { -@Test(groups = "live", testName = "CrumbIssuerApiLiveTest", singleThreaded = true) -public class CrumbIssuerApiLiveTest extends BaseJenkinsApiLiveTest { - - @Test - public void testGetCrumb() { - final Crumb crumb = api().crumb(); - assertNotNull(crumb); - assertNotNull(crumb.value()); - assertTrue(crumb.errors().isEmpty()); - } - - private CrumbIssuerApi api() { - return api.crumbIssuerApi(); - } +// // @Named("crumb-issuer:crumb") +// @Fallback(JenkinsFallbacks.CrumbOnError.class) +// @ResponseParser(CrumbParser.class) +// @QueryParams(keys = {"xpath"}, values = {"concat(//crumbRequestField,\":\",//crumb)"}) +// @Consumes(MediaType.TEXT_PLAIN) +// @GetExchange + @GetExchange + ResponseEntity crumb(); } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/features/JobsApi.java b/src/main/java/io/github/hmedioni/jenkins/client/features/JobsApi.java new file mode 100644 index 0000000..e54213b --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/features/JobsApi.java @@ -0,0 +1,266 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.features; + +import com.fasterxml.jackson.databind.*; +import io.github.hmedioni.jenkins.client.binders.*; +import io.github.hmedioni.jenkins.client.domain.common.*; +import io.github.hmedioni.jenkins.client.domain.job.*; +import org.springframework.http.*; +import org.springframework.lang.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.service.annotation.*; + +import java.io.*; +import java.util.*; + +//@RequestFilters(JenkinsAuthenticationFilter.class) +//@Path("/") +@HttpExchange(url = "/", accept = MediaType.APPLICATION_JSON_VALUE, contentType = MediaType.APPLICATION_JSON_VALUE) +public interface JobsApi { + + // // @Named("jobs:get-jobs") +// @Path("{folderPath}api/json") +// @Fallback(Fallbacks.NullOnNotFoundOr404.class) +// @Consumes(MediaType.APPLICATION_JSON) +// @GetExchange + @GetExchange("/${folderPath}api/json") + ResponseEntity jobList(@PathVariable("folderPath") String folderPath); + + // @Named("jobs:job-info") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) +// @Consumes(MediaType.APPLICATION_JSON) + @GetExchange("{optionalFolderPath}job/{name}/api/json") + JobInfo jobInfo(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:artifact") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) +// @Consumes(MediaType.APPLICATION_JSON) + @GetExchange("{optionalFolderPath}job/{name}/{number}/api/json") + BuildInfo buildInfo(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber); + + // @Named("jobs:artifact") +// @Consumes(MediaType.WILDCARD) + @GetExchange("{optionalFolderPath}job/{name}/{number}/artifact/{relativeArtifactPath}") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + InputStream artifact(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber, + @PathVariable("relativeArtifactPath") String relativeArtifactPath); + + // @Named("jobs:create") + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) +// @ResponseParser(RequestStatusParser.class) +// @Produces(MediaType.APPLICATION_XML) +// @Consumes(MediaType.WILDCARD) + // @Payload("{configXML}") + @PostExchange("{optionalFolderPath}createItem") + RequestStatus create(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @RequestParam("name") String jobName, + @RequestBody String configXML); + + // @Named("jobs:get-config") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) +// @Consumes(MediaType.TEXT_PLAIN) + @GetExchange("{optionalFolderPath}job/{name}/config.xml") + String config(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:update-config") + // @Fallback(Fallbacks.FalseOnNotFoundOr404.class) +// @Produces(MediaType.APPLICATION_XML + ";charset=UTF-8") +// @Consumes(MediaType.TEXT_HTML) + // @Payload("{configXML}") + @PostExchange("{optionalFolderPath}job/{name}/config.xml") + boolean config(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, +// @PayloadParam(value = "configXML") + String configXML); + + // @Named("jobs:get-description") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) +// @Consumes(MediaType.TEXT_PLAIN) + @GetExchange("{optionalFolderPath}job/{name}/description") + String description(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:set-description") + // @Fallback(Fallbacks.FalseOnNotFoundOr404.class) +// @Consumes(MediaType.TEXT_HTML) + @PostExchange("{optionalFolderPath}job/{name}/description") + boolean description(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @RequestParam("description") String description); + + // @Named("jobs:delete") + // @Consumes(MediaType.TEXT_HTML) + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) + //@ResponseParser(RequestStatusParser.class) + @PostExchange("{optionalFolderPath}job/{name}/doDelete") + RequestStatus delete(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:enable") + @PostExchange("{optionalFolderPath}job/{name}/enable") + // @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + // @Consumes(MediaType.TEXT_HTML) + boolean enable(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:disable") + @PostExchange("{optionalFolderPath}job/{name}/disable") + // @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + // @Consumes(MediaType.TEXT_HTML) + boolean disable(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:build") + @PostExchange("{optionalFolderPath}job/{name}/build") + // @Fallback(JenkinsFallbacks.IntegerResponseOnError.class) + //@ResponseParser(LocationToQueueId.class) + // @Consumes("application/unknown") + IntegerResponse build(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:stop-build") + @PostExchange("{optionalFolderPath}job/{name}/{number}/stop") + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) + //@ResponseParser(RequestStatusParser.class) + // @Consumes(MediaType.APPLICATION_JSON) + RequestStatus stop(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber); + + // @Named("jobs:term-build") + @PostExchange("{optionalFolderPath}job/{name}/{number}/term") + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) + //@ResponseParser(RequestStatusParser.class) + // @Consumes(MediaType.APPLICATION_JSON) + RequestStatus term(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber); + + // @Named("jobs:kill-build") + @PostExchange("{optionalFolderPath}job/{name}/{number}/kill") + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) + //@ResponseParser(RequestStatusParser.class) + // @Consumes(MediaType.APPLICATION_JSON) + RequestStatus kill(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber); + + // @Named("jobs:build-with-params") + @PostExchange("{optionalFolderPath}job/{name}/buildWithParameters") + // @Fallback(JenkinsFallbacks.IntegerResponseOnError.class) + //@ResponseParser(LocationToQueueId.class) + // @Consumes("application/unknown") + IntegerResponse buildWithParameters(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @Nullable @RequestBody Map> properties); + + // @Named("jobs:last-build-number") + @GetExchange("{optionalFolderPath}job/{name}/lastBuild/buildNumber") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + //@ResponseParser(BuildNumberToInteger.class) + // @Consumes(MediaType.TEXT_PLAIN) + + Integer lastBuildNumber(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:last-build-timestamp") + @GetExchange("{optionalFolderPath}job/{name}/lastBuild/buildTimestamp") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + // @Consumes(MediaType.TEXT_PLAIN) + + String lastBuildTimestamp(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:progressive-text") + @GetExchange("{optionalFolderPath}job/{name}/lastBuild/logText/progressiveText") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + //@ResponseParser(OutputToProgressiveText.class) + // @Consumes(MediaType.TEXT_PLAIN) + + ProgressiveText progressiveText(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @RequestParam("start") int start); + + // @Named("jobs:progressive-text") + @GetExchange("{optionalFolderPath}job/{name}/{number}/logText/progressiveText") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + //@ResponseParser(OutputToProgressiveText.class) + // @Consumes(MediaType.TEXT_PLAIN) + ProgressiveText progressiveText(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber, + @RequestParam("start") int start); + + // @Named("jobs:rename") + @PostExchange("{optionalFolderPath}job/{name}/doRename") + // @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + // @Consumes(MediaType.TEXT_HTML) + boolean rename(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @RequestParam("newName") String newName); + + // below four apis are for "pipeline-stage-view-plugin", + // see https://github.com/jenkinsci/pipeline-stage-view-plugin/tree/master/rest-api + // @Named("jobs:run-history") + @GetExchange("{optionalFolderPath}job/{name}/wfapi/runs") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + // @Consumes(MediaType.APPLICATION_JSON) + List runHistory(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName); + + // @Named("jobs:workflow") + @GetExchange("{optionalFolderPath}job/{name}/{number}/wfapi/describe") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + // @Consumes(MediaType.APPLICATION_JSON) + Workflow workflow(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber); + + // @Named("jobs:pipeline-node") + @GetExchange("{optionalFolderPath}job/{name}/{number}/execution/node/{nodeId}/wfapi/describe") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + // @Consumes(MediaType.APPLICATION_JSON) + PipelineNode pipelineNode(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber, @PathVariable("nodeId") int nodeId); + + // @Named("jobs:pipeline-node-log") +// // @Fallback(Fallbacks.NullOnNotFoundOr404.class) +// @Consumes(MediaType.APPLICATION_JSON) + @GetExchange("{optionalFolderPath}job/{name}/{number}/execution/node/{nodeId}/wfapi/log") + ResponseEntity pipelineNodeLog(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber, @PathVariable("nodeId") int nodeId); + + // @Named("jobs:testReport") +// // @Fallback(Fallbacks.NullOnNotFoundOr404.class) +// @Consumes(MediaType.APPLICATION_JSON) +// @GetExchange + @GetExchange("${optionalFolderPath}job/{name}/{number}/testReport/api/json") + ResponseEntity testReport(@Nullable @PathVariable("optionalFolderPath") String optionalFolderPath, + @PathVariable("name") String jobName, + @PathVariable("number") int buildNumber); + +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/features/PluginManagerApi.java b/src/main/java/io/github/hmedioni/jenkins/client/features/PluginManagerApi.java new file mode 100644 index 0000000..fa3001b --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/features/PluginManagerApi.java @@ -0,0 +1,48 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.features; + +import io.github.hmedioni.jenkins.client.domain.common.*; +import io.github.hmedioni.jenkins.client.domain.plugins.*; +import org.springframework.http.*; +import org.springframework.lang.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.service.annotation.*; + + +//@RequestFilters(JenkinsAuthenticationFilter.class) +//@Consumes(MediaType.APPLICATION_JSON) +//@Path("/pluginManager") +@HttpExchange(value = "/pluginManager", accept = MediaType.APPLICATION_JSON_VALUE, contentType = MediaType.APPLICATION_JSON_VALUE) +public interface PluginManagerApi { + + // @Named("pluginManager:plugins") + // @Fallback(JenkinsFallbacks.PluginsOnError.class) + @GetExchange("/api/json") + + Plugins plugins(@Nullable @RequestParam("depth") Integer depth, + @Nullable @RequestParam("tree") String tree); + + // @Named("pluginManager:install-necessary-plugins") + @PostExchange("/installNecessaryPlugins") + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) + //@ResponseParser(RequestStatusParser.class) + // @Produces(MediaType.APPLICATION_XML) + // @Payload("") + RequestStatus installNecessaryPlugins(@RequestBody String pluginID); +} diff --git a/src/main/java/com/cdancy/jenkins/rest/features/QueueApi.java b/src/main/java/io/github/hmedioni/jenkins/client/features/QueueApi.java similarity index 54% rename from src/main/java/com/cdancy/jenkins/rest/features/QueueApi.java rename to src/main/java/io/github/hmedioni/jenkins/client/features/QueueApi.java index bbc1fd3..e9cc9c7 100644 --- a/src/main/java/com/cdancy/jenkins/rest/features/QueueApi.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/features/QueueApi.java @@ -15,65 +15,51 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.features; +package io.github.hmedioni.jenkins.client.features; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import java.util.List; +import io.github.hmedioni.jenkins.client.domain.common.*; +import io.github.hmedioni.jenkins.client.domain.queue.*; -import javax.inject.Named; -import javax.ws.rs.Consumes; -import javax.ws.rs.FormParam; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.MediaType; +import io.github.hmedioni.jenkins.client.filters.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.service.annotation.*; -import org.jclouds.rest.annotations.Fallback; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.SelectJson; +import java.util.*; -import com.cdancy.jenkins.rest.domain.queue.QueueItem; -import com.cdancy.jenkins.rest.fallbacks.JenkinsFallbacks; -import com.cdancy.jenkins.rest.filters.JenkinsAuthenticationFilter; -import com.cdancy.jenkins.rest.parsers.RequestStatusParser; -import org.jclouds.rest.annotations.ResponseParser; - -@RequestFilters(JenkinsAuthenticationFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -@Path("/queue") +// @RequestFilters(JenkinsAuthenticationFilter.class) +// @Consumes(MediaType.APPLICATION_JSON) +@HttpExchange("/queue") public interface QueueApi { - @Named("queue:queue") - @Path("/api/json") - @SelectJson("items") - @GET + // @Named("queue:queue") + @GetExchange("/api/json") +// @SelectJson("items") List queue(); /** * Get a specific queue item. - * + *

    * Queue items are builds that have been scheduled to run, but are waiting for a slot. * You can poll the queueItem that corresponds to a build to detect whether the build is still pending or is executing. + * * @param queueId The queue id value as returned by the JobsApi build or buildWithParameters methods. * @return The queue item corresponding to the queue id. */ - @Named("queue:item") - @Path("/item/{queueId}/api/json") - @GET - QueueItem queueItem(@PathParam("queueId") int queueId); + // @Named("queue:item") + @GetExchange("/item/{queueId}/api/json") + QueueItem queueItem(@PathVariable("queueId") int queueId); /** * Cancel a queue item before it gets built. - * + * * @param id The queue id value of the queue item to cancel. * This is the value is returned by the JobsApi build or buildWithParameters methods. * @return Always returns true due to JENKINS-21311. */ - @Named("queue:cancel") - @Path("/cancelItem") - @Fallback(JenkinsFallbacks.JENKINS_21311.class) - @ResponseParser(RequestStatusParser.class) - @POST - RequestStatus cancel(@FormParam("id") int id); + // @Named("queue:cancel") + @PostExchange("/cancelItem") + // @Fallback(JenkinsFallbacks.JENKINS_21311.class) + //@ResponseParser(RequestStatusParser.class) + //@FormParam("id") + RequestStatus cancel(@RequestBody int id); } diff --git a/src/main/java/com/cdancy/jenkins/rest/features/StatisticsApi.java b/src/main/java/io/github/hmedioni/jenkins/client/features/StatisticsApi.java similarity index 59% rename from src/main/java/com/cdancy/jenkins/rest/features/StatisticsApi.java rename to src/main/java/io/github/hmedioni/jenkins/client/features/StatisticsApi.java index f631255..895dfc5 100644 --- a/src/main/java/com/cdancy/jenkins/rest/features/StatisticsApi.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/features/StatisticsApi.java @@ -15,26 +15,19 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.features; +package io.github.hmedioni.jenkins.client.features; -import javax.inject.Named; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.core.MediaType; +import io.github.hmedioni.jenkins.client.domain.statistics.*; +import org.springframework.http.*; +import org.springframework.web.service.annotation.*; -import org.jclouds.rest.annotations.RequestFilters; -import com.cdancy.jenkins.rest.domain.statistics.OverallLoad; -import com.cdancy.jenkins.rest.filters.JenkinsAuthenticationFilter; - -@RequestFilters(JenkinsAuthenticationFilter.class) -@Consumes(MediaType.APPLICATION_JSON) -@Path("/") +// @RequestFilters(JenkinsAuthenticationFilter.class) +// @Consumes(MediaType.APPLICATION_JSON) +@HttpExchange(value = "/", accept = MediaType.APPLICATION_JSON_VALUE, contentType = MediaType.APPLICATION_JSON_VALUE) public interface StatisticsApi { - @Named("statistics:overall-load") - @Path("/overallLoad/api/json") - @GET - OverallLoad overallLoad(); + // @Named("statistics:overall-load") + @GetExchange("/overallLoad/api/json") + OverallLoad overallLoad(); } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/features/SystemApi.java b/src/main/java/io/github/hmedioni/jenkins/client/features/SystemApi.java new file mode 100644 index 0000000..f766e74 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/features/SystemApi.java @@ -0,0 +1,50 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.features; + +import io.github.hmedioni.jenkins.client.domain.common.*; +import io.github.hmedioni.jenkins.client.domain.system.*; +import org.springframework.web.service.annotation.*; + + +// @RequestFilters(JenkinsAuthenticationFilter.class) +// @Consumes(MediaType.APPLICATION_JSON) +@HttpExchange("/") +public interface SystemApi { + + // @Named("system:info") + // @Fallback(JenkinsFallbacks.SystemInfoOnError.class) + //@ResponseParser(SystemInfoFromJenkinsHeaders.class) + @HttpExchange(method = "HEAD") + SystemInfo systemInfo(); + + // @Named("system:quiet-down") + @PostExchange("quietDown") + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) + //@ResponseParser(RequestStatusParser.class) + // @Consumes(MediaType.TEXT_HTML) + RequestStatus quietDown(); + + // @Named("system:cancel-quiet-down") + @PostExchange("cancelQuietDown") + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) + //@ResponseParser(RequestStatusParser.class) + // @Consumes(MediaType.TEXT_HTML) + RequestStatus cancelQuietDown(); + +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/features/UserApi.java b/src/main/java/io/github/hmedioni/jenkins/client/features/UserApi.java new file mode 100644 index 0000000..0d46d94 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/features/UserApi.java @@ -0,0 +1,58 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.features; + +import io.github.hmedioni.jenkins.client.domain.common.*; +import io.github.hmedioni.jenkins.client.domain.user.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.service.annotation.*; + + +/** + * The UserApi. + *

    + * Implements some of the User Rest Api defined in Jenkins. + * For the User Api, see User.java + * For the Api Token, see ApiTokenProperty.java. + */ +// @RequestFilters({JenkinsAuthenticationFilter.class, JenkinsUserInjectionFilter.class}) +@HttpExchange("/user") +public interface UserApi { + + // @Named("user:get") + @GetExchange("/{user}/api/json") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + // @Consumes(MediaType.APPLICATION_JSON) + User get(); + + // @Named("user:generateNewToken") + @PostExchange("/{user}/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken") + // @Fallback(Fallbacks.NullOnNotFoundOr404.class) + // @Consumes(MediaType.APPLICATION_JSON) + // @Produces(MediaType.APPLICATION_FORM_URLENCODED) + // @Payload("newTokenName={tokenName}") + ApiToken generateNewToken(@RequestBody String tokenName); + + // @Named("user:revoke") + @PostExchange("/{user}/descriptorByName/jenkins.security.ApiTokenProperty/revoke") + // @Fallback(JenkinsFallbacks.RequestStatusOnError.class) + //@ResponseParser(RequestStatusParser.class) + // @Produces(MediaType.APPLICATION_FORM_URLENCODED) +// @Payload("tokenUuid={tokenUuid}") + RequestStatus revoke(@RequestBody String tokenUuid); +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilter.java b/src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilter.java new file mode 100644 index 0000000..fdbb3a4 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilter.java @@ -0,0 +1,79 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.filters; + +import io.github.hmedioni.jenkins.client.*; +import io.github.hmedioni.jenkins.client.auth.*; +import io.github.hmedioni.jenkins.client.domain.crumb.*; +import io.github.hmedioni.jenkins.client.exception.*; +import org.springframework.http.*; +import org.springframework.http.HttpHeaders; +import org.springframework.web.reactive.function.client.*; +import reactor.core.publisher.*; + +import java.net.http.*; +import java.util.*; + +public class JenkinsAuthenticationFilter implements ExchangeFilterFunction { + + private static final String CRUMB_HEADER = "Jenkins-Crumb"; + private final JenkinsAuthentication creds; + private final JenkinsApi jenkinsApi; + + // key = Crumb, value = true if exception is ResourceNotFoundException false otherwise + public JenkinsAuthenticationFilter(final JenkinsAuthentication creds, JenkinsApi jenkinsApi) { + this.creds = creds; + } + + @Override + public Mono filter(ClientRequest request, ExchangeFunction next) { + ClientRequest.Builder builder = ClientRequest.from(request); + + // Password and API Token are both Basic authentication (there is no Bearer authentication in Jenkins) + if (creds.authType() == AuthenticationType.USERNAME_API_TOKEN || creds.authType() == AuthenticationType.USERNAME_PASSWORD) { + final String authHeader = creds.authType().getAuthScheme() + " " + creds.authValue(); + builder.header(org.springframework.http.HttpHeaders.AUTHORIZATION, authHeader); + } + + // Anon and Password need the crumb and the cookie when POSTing +// if (request.method().equals(HttpMethod.POST) && (creds.authType() == AuthenticationType.USERNAME_PASSWORD +// || creds.authType() == AuthenticationType.ANONYMOUS)) { +// final CrumbWrapper localCrumb = getCrumb(); +// if (localCrumb.getCrumb() != null) { +// builder.header(CRUMB_HEADER, localCrumb.getCrumb().getValue()); +// Optional.ofNullable(localCrumb.getCrumb().getSessionIdCookie()) +// .ifPresent(sessionId -> builder.header(org.springframework.http.HttpHeaders.COOKIE, sessionId)); +// } else { +// if (Boolean.FALSE.equals(localCrumb.getABoolean())) { +// throw new RuntimeException("Unexpected exception being thrown: error="); +// } +// } +// } + return next.exchange(builder.build()); + } + +// private CrumbWrapper getCrumb() { +// try { +// final Crumb crumb = jenkinsApi.crumbIssuerApi().crumb(null).getBody(); +// return new CrumbWrapper(crumb, true); +// } catch (JenkinsAppException e) { +// return new CrumbWrapper(null, false); +// } +// } +// +} diff --git a/src/main/java/com/cdancy/jenkins/rest/filters/JenkinsNoCrumbAuthenticationFilter.java b/src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsNoCrumbAuthenticationFilter.java similarity index 59% rename from src/main/java/com/cdancy/jenkins/rest/filters/JenkinsNoCrumbAuthenticationFilter.java rename to src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsNoCrumbAuthenticationFilter.java index 9a65583..950b956 100644 --- a/src/main/java/com/cdancy/jenkins/rest/filters/JenkinsNoCrumbAuthenticationFilter.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsNoCrumbAuthenticationFilter.java @@ -15,35 +15,33 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.filters; +package io.github.hmedioni.jenkins.client.filters; -import javax.inject.Inject; -import javax.inject.Singleton; +import io.github.hmedioni.jenkins.client.*; +import io.github.hmedioni.jenkins.client.auth.*; +import org.springframework.http.*; +import org.springframework.web.reactive.function.client.*; +import reactor.core.publisher.*; -import com.cdancy.jenkins.rest.JenkinsAuthentication; -import com.cdancy.jenkins.rest.auth.AuthenticationType; -import org.jclouds.http.HttpException; -import org.jclouds.http.HttpRequest; -import org.jclouds.http.HttpRequestFilter; -import com.google.common.net.HttpHeaders; - -@Singleton -public class JenkinsNoCrumbAuthenticationFilter implements HttpRequestFilter { +public class JenkinsNoCrumbAuthenticationFilter implements ExchangeFilterFunction { private final JenkinsAuthentication creds; - @Inject JenkinsNoCrumbAuthenticationFilter(final JenkinsAuthentication creds) { this.creds = creds; } + @Override - public HttpRequest filter(final HttpRequest request) throws HttpException { - if (creds.authType() == AuthenticationType.Anonymous) { - return request; + public Mono filter(ClientRequest request, ExchangeFunction next) { + if (creds.authType() == AuthenticationType.ANONYMOUS) { + return next.exchange(request); } else { final String authHeader = creds.authType().getAuthScheme() + " " + creds.authValue(); - return request.toBuilder().addHeader(HttpHeaders.AUTHORIZATION, authHeader).build(); + final ClientRequest newRequest = ClientRequest.from(request) + .header(HttpHeaders.AUTHORIZATION, authHeader) + .build(); + return next.exchange(newRequest); } } } diff --git a/src/main/java/com/cdancy/jenkins/rest/filters/JenkinsUserInjectionFilter.java b/src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsUserInjectionFilter.java similarity index 59% rename from src/main/java/com/cdancy/jenkins/rest/filters/JenkinsUserInjectionFilter.java rename to src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsUserInjectionFilter.java index 7338906..84fe5e2 100644 --- a/src/main/java/com/cdancy/jenkins/rest/filters/JenkinsUserInjectionFilter.java +++ b/src/main/java/io/github/hmedioni/jenkins/client/filters/JenkinsUserInjectionFilter.java @@ -15,32 +15,32 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest.filters; +package io.github.hmedioni.jenkins.client.filters; -import org.jclouds.http.HttpException; -import org.jclouds.http.HttpRequest; -import org.jclouds.http.HttpRequestFilter; +import io.github.hmedioni.jenkins.client.*; +import org.springframework.http.*; +import org.springframework.web.reactive.function.client.*; +import reactor.core.publisher.*; -import com.cdancy.jenkins.rest.JenkinsAuthentication; -import static com.cdancy.jenkins.rest.JenkinsConstants.USER_IN_USER_API; -import javax.inject.Inject; -import javax.inject.Singleton; +import java.net.*; -@Singleton -public class JenkinsUserInjectionFilter implements HttpRequestFilter { +import static io.github.hmedioni.jenkins.client.JenkinsConstants.*; + +public class JenkinsUserInjectionFilter implements ExchangeFilterFunction { private static final String USER_PLACE_HOLDER = "%7B" + USER_IN_USER_API + "%7D"; private final JenkinsAuthentication creds; - @Inject public JenkinsUserInjectionFilter(final JenkinsAuthentication creds) { this.creds = creds; } + @Override - public HttpRequest filter(final HttpRequest request) throws HttpException { - final String requestPath = request.getEndpoint().getRawPath().replaceAll(USER_PLACE_HOLDER, creds.identity); - return request.toBuilder().fromHttpRequest(request).replacePath(requestPath).build(); + public Mono filter(ClientRequest request, ExchangeFunction next) { + ClientRequest.Builder builder = ClientRequest.from(request); + builder.url(URI.create(request.url().getRawPath().replaceAll(USER_PLACE_HOLDER, creds.authValue()))); + return next.exchange(builder.build()); } } diff --git a/src/main/java/io/github/hmedioni/jenkins/client/filters/ScrubNullFolderParam.java b/src/main/java/io/github/hmedioni/jenkins/client/filters/ScrubNullFolderParam.java new file mode 100644 index 0000000..474cf58 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/filters/ScrubNullFolderParam.java @@ -0,0 +1,53 @@ +/* + * 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. + */ + +package io.github.hmedioni.jenkins.client.filters; + +import org.springframework.web.reactive.function.client.*; +import reactor.core.publisher.*; + + +import java.net.*; + + +public class ScrubNullFolderParam implements ExchangeFilterFunction { + + private static final String SCRUB_NULL_PARAM = "%7B.+?%7D"; + private static final String FORWARD_SLASH = "/"; + private static final String DOUBLE_FORWARD_SLASH = "\\" + FORWARD_SLASH + "\\" + FORWARD_SLASH; + private static final String EMPTY_STRING = ""; + private static final char FORWARD_SLASH_CHAR = '/'; + + + @Override + public Mono filter(ClientRequest request, ExchangeFunction next) { + String oldPath = request.url().getPath(); + String requestPath = request.url().getPath() + .replace(SCRUB_NULL_PARAM, EMPTY_STRING) + .replace(DOUBLE_FORWARD_SLASH, FORWARD_SLASH); + if (requestPath.charAt(requestPath.length() - 1) == FORWARD_SLASH_CHAR) { + requestPath = requestPath.substring(0, requestPath.length() - 1); + } + String newUrl = request.url().toString().replaceAll(oldPath, requestPath); + URI newURI = URI.create(newUrl); + + ClientRequest filteredRequest = ClientRequest.from(request) + .url(newURI) + .build(); + return next.exchange(filteredRequest); + } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/handlers/JenkinsErrorHandler.java b/src/main/java/io/github/hmedioni/jenkins/client/handlers/JenkinsErrorHandler.java new file mode 100644 index 0000000..b2485af --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/handlers/JenkinsErrorHandler.java @@ -0,0 +1,134 @@ +/* + * 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. + */ +package io.github.hmedioni.jenkins.client.handlers; + +import com.fasterxml.jackson.databind.*; +import io.github.hmedioni.jenkins.client.exception.*; +import lombok.*; +import org.springframework.http.*; +import org.springframework.web.reactive.function.client.*; +import reactor.core.publisher.*; + +import java.io.*; +import java.net.http.*; +import java.util.*; + + +/** + * Handle errors and propagate exception + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class JenkinsErrorHandler { + + private static final ObjectMapper mapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + + public static ExchangeFilterFunction handler() { + return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> { + HttpStatusCode statusCode = clientResponse.statusCode(); + if (statusCode.is5xxServerError() || statusCode.is4xxClientError()) { + return clientResponse.bodyToMono(String.class) + .defaultIfEmpty("{}") + .flatMap(errorBody -> Mono.error(new JenkinsAppException(errorBody, getErrors(errorBody, statusCode), statusCode))); + } else { + return Mono.just(clientResponse); + } + }); + } + + private static List getErrors(String errorBody, HttpStatusCode statusCode) { + return null; + } + +// @Override +// public void handleError(final HttpCommand command, final HttpResponse response) { +// +// Exception exception = null; +// try { +// final String message = parseMessage(command, response); +// +// switch (response.getStatusCode()) { +// case 400: +// if (command.getCurrentRequest().getMethod().equals("POST")) { +// if (command.getCurrentRequest().getRequestLine().contains("/createItem")) { +// if (message.contains("A job already exists with the name")) { +// exception = new ResourceAlreadyExistsException(message); +// break; +// } +// } +// } +// exception = new IllegalArgumentException(message); +// break; +// case 401: +// exception = new AuthorizationException(message); +// break; +// case 403: +// exception = new ForbiddenException(message); +// break; +// case 404: +// // When Jenkins replies to term or kill with a redirect to a non-existent URL +// // we want to return a custom error message and avoid an exception in the user code. +// if (command.getCurrentRequest().getMethod().equals("POST")) { +// final String path = command.getCurrentRequest().getEndpoint().getPath(); +// if (path.endsWith("/term/")) { +// exception = new RedirectTo404Exception("The term operation does not exist for " + command.getCurrentRequest().getEndpoint().toString() + ", try stop instead."); +// break; +// } else if (path.endsWith("/kill/")) { +// exception = new RedirectTo404Exception("The kill operation does not exist for " + command.getCurrentRequest().getEndpoint().toString() + ", try stop instead."); +// break; +// } +// } +// exception = new ResourceNotFoundException(message); +// break; +// case 405: +// exception = new MethodNotAllowedException(message); +// break; +// case 409: +// exception = new ResourceAlreadyExistsException(message); +// break; +// case 415: +// exception = new UnsupportedMediaTypeException(message); +// break; +// default: +// exception = new HttpResponseException(command, response); +// } +// } catch (Exception e) { +// exception = new HttpResponseException(command, response, e); +// } finally { +// closeQuietly(response.getPayload()); +// command.setException(exception); +// } +// } + +// private String parseMessage(final HttpCommand command, final HttpResponse response) { +// if (response.getPayload() != null) { +// try { +// return Strings2.toStringAndClose(response.getPayload().openStream()); +// } catch (IOException e) { +// throw Throwables.propagate(e); +// } +// } else { +// final String errorMessage = response.getFirstHeaderOrNull("X-Error"); +// return command.getCurrentRequest().getRequestLine() + +// " -> " + +// response.getStatusLine() + +// " -> " + +// (errorMessage != null ? errorMessage : ""); +// } +// } +} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/parsers/BuildNumberToInteger.java b/src/main/java/io/github/hmedioni/jenkins/client/parsers/BuildNumberToInteger.java new file mode 100644 index 0000000..031f9fe --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/parsers/BuildNumberToInteger.java @@ -0,0 +1,51 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client.parsers; +// +//import java.io.*; +//import java.net.http.*; +// +///** +// * Created by dancc on 3/11/16. +// */ +//public class BuildNumberToInteger { +// +// public Integer apply(HttpResponse response) { +// return Integer.valueOf(getTextOutput(response)); +// } +// +// public String getTextOutput(HttpResponse response) { +// InputStream is = null; +//// try { +//// is = response.getPayload().openStream(); +//// return CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8)).trim(); +//// } catch (Exception e) { +//// Throwables.propagate(e); +//// } finally { +//// if (is != null) { +//// try { +//// is.close(); +//// } catch (Exception e) { +//// Throwables.propagate(e); +//// } +//// } +//// } +// +// return null; +// } +//} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/parsers/CrumbParser.java b/src/main/java/io/github/hmedioni/jenkins/client/parsers/CrumbParser.java new file mode 100644 index 0000000..1ac3815 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/parsers/CrumbParser.java @@ -0,0 +1,76 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client.parsers; +// +//import com.google.common.base.*; +//import io.github.hmedioni.jenkins.client.domain.crumb.*; +//import org.jclouds.http.*; +//import org.jclouds.util.*; +// +//import javax.inject.*; +// +//import java.io.*; +//import java.util.*; +// +//import static io.github.hmedioni.jenkins.client.JenkinsConstants.*; +// +///** +// * Turn a valid response, but one that has no body, into a Crumb. +// */ +//@Singleton +//public class CrumbParser implements Function { +// +// private static String crumbValue(HttpResponse input) throws IOException { +// return Strings2.toStringAndClose(input.getPayload().openStream()) +// .split(":")[1]; +// } +// +// private static String sessionIdCookie(HttpResponse input) { +// return setCookieValues(input).stream() +// .filter(c -> c.startsWith(JENKINS_COOKIES_JSESSIONID)) +// .findFirst() +// .orElse(""); +// } +// +// private static Collection setCookieValues(HttpResponse input) { +// Collection setCookieValues = input.getHeaders().get(HttpHeaders.SET_COOKIE); +// if (setCookieValues.isEmpty()) { +// return input.getHeaders().get(HttpHeaders.SET_COOKIE.toLowerCase()); +// } else { +// return setCookieValues; +// } +// } +// +// @Override +// public Crumb apply(final HttpResponse input) { +// if (input == null) { +// throw new RuntimeException("Unexpected NULL HttpResponse object"); +// } +// +// final int statusCode = input.getStatusCode(); +// if (statusCode >= 200 && statusCode < 400) { +// try { +// return Crumb.create(crumbValue(input), sessionIdCookie(input)); +// } catch (final IOException e) { +// throw new RuntimeException(input.getStatusLine(), e); +// } +// } else { +// throw new RuntimeException(input.getStatusLine()); +// } +// } +//} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/parsers/FolderPathParser.java b/src/main/java/io/github/hmedioni/jenkins/client/parsers/FolderPathParser.java new file mode 100644 index 0000000..81609f1 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/parsers/FolderPathParser.java @@ -0,0 +1,49 @@ +//package io.github.hmedioni.jenkins.client.parsers; +// +//import com.google.common.base.*; +// +//import javax.inject.*; +// +///* +// * Turn the optionalFolderPath param to jenkins URL style +// */ +//@Singleton +//public class FolderPathParser implements Function { +// +// public static final String EMPTY_STRING = ""; +// public static final String FOLDER_NAME_PREFIX = "job/"; +// public static final Character FOLDER_NAME_SEPARATOR = '/'; +// +// @Override +// public String apply(Object folderPath) { +// if (folderPath == null) { +// return EMPTY_STRING; +// } +// +// final StringBuilder path = new StringBuilder((String) folderPath); +// if (path.length() == 0) { +// return EMPTY_STRING; +// } +// +// if (path.charAt(0) == FOLDER_NAME_SEPARATOR) { +// path.deleteCharAt(0); +// } +// if (path.length() == 0) { +// return EMPTY_STRING; +// } +// +// if (path.charAt(path.length() - 1) == FOLDER_NAME_SEPARATOR) { +// path.deleteCharAt(path.length() - 1); +// } +// if (path.length() == 0) { +// return EMPTY_STRING; +// } +// +// final String[] folders = path.toString().split(Character.toString(FOLDER_NAME_SEPARATOR)); +// path.setLength(0); +// for (final String folder : folders) { +// path.append(FOLDER_NAME_PREFIX).append(folder).append(FOLDER_NAME_SEPARATOR); +// } +// return path.toString(); +// } +//} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/parsers/LocationToQueueId.java b/src/main/java/io/github/hmedioni/jenkins/client/parsers/LocationToQueueId.java new file mode 100644 index 0000000..0a28462 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/parsers/LocationToQueueId.java @@ -0,0 +1,53 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client.parsers; +// +//import com.google.common.base.*; +//import io.github.hmedioni.jenkins.client.domain.common.Error; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import org.jclouds.http.*; +// +//import javax.inject.*; +//import java.util.regex.*; +// +///** +// * Created by dancc on 3/11/16. +// */ +//@Singleton +//public class LocationToQueueId implements Function { +// +// private static final Pattern pattern = Pattern.compile("^.*/queue/item/(\\d+)/$"); +// +// public IntegerResponse apply(HttpResponse response) { +// if (response == null) { +// throw new RuntimeException("Unexpected NULL HttpResponse object"); +// } +// +// String url = response.getFirstHeaderOrNull("Location"); +// if (url != null) { +// Matcher matcher = pattern.matcher(url); +// if (matcher.find() && matcher.groupCount() == 1) { +// return IntegerResponse.create(Integer.valueOf(matcher.group(1)), null); +// } +// } +// final Error error = Error.create(null, +// "No queue item Location header could be found despite getting a valid HTTP response.", +// NumberFormatException.class.getCanonicalName()); +// return IntegerResponse.create(null, Lists.newArrayList(error)); +// } +//} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/parsers/OptionalFolderPathParser.java b/src/main/java/io/github/hmedioni/jenkins/client/parsers/OptionalFolderPathParser.java new file mode 100644 index 0000000..cfeab03 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/parsers/OptionalFolderPathParser.java @@ -0,0 +1,50 @@ +//package io.github.hmedioni.jenkins.client.parsers; +// +// +///* +// * Turn the optionalFolderPath param to jenkins URL style +// */ +// +//import lombok.*; +// +//@NoArgsConstructor(access = AccessLevel.PRIVATE) +//public class OptionalFolderPathParser { +// +// +// public static final String EMPTY_STRING = ""; +// public static final String FOLDER_NAME_PREFIX = "job/"; +// public static final Character FOLDER_NAME_SEPARATOR = '/'; +// +// public static String apply(Object optionalFolderPath) { +// if (optionalFolderPath == null) { +// return EMPTY_STRING; +// } +// +// final StringBuilder path = new StringBuilder((String) optionalFolderPath); +// if (path.length() == 0) { +// return EMPTY_STRING; +// } +// +// if (path.charAt(0) == FOLDER_NAME_SEPARATOR) { +// path.deleteCharAt(0); +// } +// if (path.length() == 0) { +// return EMPTY_STRING; +// } +// +// if (path.charAt(path.length() - 1) == FOLDER_NAME_SEPARATOR) { +// path.deleteCharAt(path.length() - 1); +// } +// if (path.length() == 0) { +// return EMPTY_STRING; +// } +// +// final String[] folders = path.toString().split(Character.toString(FOLDER_NAME_SEPARATOR)); +// path.setLength(0); +// for (final String folder : folders) { +// path.append(FOLDER_NAME_PREFIX).append(folder).append(FOLDER_NAME_SEPARATOR); +// } +// +// return path.toString(); +// } +//} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/parsers/OutputToProgressiveText.java b/src/main/java/io/github/hmedioni/jenkins/client/parsers/OutputToProgressiveText.java new file mode 100644 index 0000000..54b1033 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/parsers/OutputToProgressiveText.java @@ -0,0 +1,62 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client.parsers; +// +//import com.google.common.base.*; +//import com.google.common.io.*; +//import io.github.hmedioni.jenkins.client.domain.job.*; +//import org.jclouds.http.*; +// +//import javax.inject.*; +//import java.io.*; +// +///** +// * Created by dancc on 3/11/16. +// */ +//@Singleton +//public class OutputToProgressiveText implements Function { +// +// public ProgressiveText apply(HttpResponse response) { +// +// String text = getTextOutput(response); +// int size = getTextSize(response); +// boolean hasMoreData = getMoreData(response); +// return ProgressiveText.create(text, size, hasMoreData); +// } +// +// public String getTextOutput(HttpResponse response) { +// try (InputStream is = response.getPayload().openStream()) { +// return CharStreams.toString(new InputStreamReader(is, Charsets.UTF_8)); +// } catch (Exception e) { +// // ignore +// } +// // ignore +// +// return null; +// } +// +// public int getTextSize(HttpResponse response) { +// String textSize = response.getFirstHeaderOrNull("X-Text-Size"); +// return textSize != null ? Integer.parseInt(textSize) : -1; +// } +// +// public boolean getMoreData(HttpResponse response) { +// String moreData = response.getFirstHeaderOrNull("X-More-Data"); +// return Boolean.parseBoolean(moreData); +// } +//} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/parsers/RequestStatusParser.java b/src/main/java/io/github/hmedioni/jenkins/client/parsers/RequestStatusParser.java new file mode 100644 index 0000000..88e44a6 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/parsers/RequestStatusParser.java @@ -0,0 +1,45 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client.parsers; +// +//import com.google.common.base.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import org.jclouds.http.*; +// +//import javax.inject.*; +// +///** +// * Turn a valid response, but one that has no body, into a RequestStatus. +// */ +//@Singleton +//public class RequestStatusParser implements Function { +// +// @Override +// public RequestStatus apply(final HttpResponse input) { +// if (input == null) { +// throw new RuntimeException("Unexpected NULL HttpResponse object"); +// } +// +// final int statusCode = input.getStatusCode(); +// if (statusCode >= 200 && statusCode < 400) { +// return RequestStatus.create(true, null); +// } else { +// throw new RuntimeException(input.getStatusLine()); +// } +// } +//} diff --git a/src/main/java/io/github/hmedioni/jenkins/client/parsers/SystemInfoFromJenkinsHeaders.java b/src/main/java/io/github/hmedioni/jenkins/client/parsers/SystemInfoFromJenkinsHeaders.java new file mode 100644 index 0000000..3415d76 --- /dev/null +++ b/src/main/java/io/github/hmedioni/jenkins/client/parsers/SystemInfoFromJenkinsHeaders.java @@ -0,0 +1,48 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client.parsers; +// +//import com.google.common.base.*; +//import io.github.hmedioni.jenkins.client.domain.system.*; +//import org.jclouds.http.*; +// +//import javax.inject.*; +// +///** +// * Created by dancc on 3/11/16. +// */ +//@Singleton +//public class SystemInfoFromJenkinsHeaders implements Function { +// +// @Override +// public SystemInfo apply(HttpResponse response) { +// if (response == null) { +// throw new RuntimeException("Unexpected NULL HttpResponse object"); +// } +// +// final int statusCode = response.getStatusCode(); +// if (statusCode >= 200 && statusCode < 400) { +// return SystemInfo.create(response.getFirstHeaderOrNull("X-Hudson"), response.getFirstHeaderOrNull("X-Jenkins"), +// response.getFirstHeaderOrNull("X-Jenkins-Session"), +// response.getFirstHeaderOrNull("X-Instance-Identity"), response.getFirstHeaderOrNull("X-SSH-Endpoint"), +// response.getFirstHeaderOrNull("Server"), null); +// } else { +// throw new RuntimeException(response.getStatusLine()); +// } +// } +//} diff --git a/src/test/java/com/cdancy/jenkins/rest/BaseJenkinsMockTest.java b/src/test/java/com/cdancy/jenkins/rest/BaseJenkinsMockTest.java deleted file mode 100644 index 68a9178..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/BaseJenkinsMockTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest; - -import java.io.IOException; -import java.util.Map; - -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; - -import com.google.common.base.Functions; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import com.google.gson.JsonParser; -import okhttp3.mockwebserver.MockWebServer; -import okhttp3.mockwebserver.RecordedRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.testng.Assert.assertEquals; - -/** - * Base class for all Jenkins mock tests. - */ -public class BaseJenkinsMockTest extends BaseJenkinsTest { - - /** - * Create a MockWebServer with an initial bread-crumb response. - * - * @return instance of MockWebServer - * @throws IOException - * if unable to start/play server - */ - public static MockWebServer mockWebServer() throws IOException { - final MockWebServer server = new MockWebServer(); - server.start(); - return server; - } - - private static Map extractParams(final String path) { - - final int qmIndex = path.indexOf('?'); - if (qmIndex <= 0) { - return ImmutableMap.of(); - } - - final ImmutableMap.Builder builder = ImmutableMap.builder(); - - final String[] params = path.substring(qmIndex + 1).split("&"); - for (final String param : params) { - final String[] keyValue = param.split("=", 2); - if (keyValue.length > 1) { - builder.put(keyValue[0], keyValue[1]); - } - } - - return builder.build(); - } - - protected RecordedRequest assertSent(final MockWebServer server, - final String method, - final String path) throws InterruptedException { - - return assertSent(server, method, path, ImmutableMap. of()); - } - - protected RecordedRequest assertSent(final MockWebServer server, - final String method, - final String expectedPath, - final Map queryParams) throws InterruptedException { - - RecordedRequest request = server.takeRequest(); - assertThat(request.getMethod()).isEqualTo(method); - assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON); - - final String path = request.getPath(); - final String rawPath = path.contains("?") ? path.substring(0, path.indexOf('?')) : path; - assertThat(rawPath).isEqualTo(expectedPath); - - final Map normalizedParams = Maps.transformValues(queryParams, Functions.toStringFunction()); - assertThat(normalizedParams).isEqualTo(extractParams(path)); - - return request; - } - - protected RecordedRequest assertSentWithFormData(final MockWebServer server, - final String method, - final String path, - final String body) throws InterruptedException { - - RecordedRequest request = server.takeRequest(); - assertThat(request.getMethod()).isEqualTo(method); - assertThat(request.getPath()).isEqualTo(path); - assertThat(request.getUtf8Body()).isEqualTo(body); - assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON); - assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo(MediaType.APPLICATION_FORM_URLENCODED); - return request; - } - - protected RecordedRequest assertSentWithFormData(MockWebServer server, String method, - String path, String body, - String acceptType) throws InterruptedException { - - RecordedRequest request = server.takeRequest(); - assertThat(request.getMethod()).isEqualTo(method); - assertThat(request.getPath()).isEqualTo(path); - assertThat(request.getUtf8Body()).isEqualTo(body); - assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(acceptType); - assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo(MediaType.APPLICATION_FORM_URLENCODED); - return request; - } - - protected RecordedRequest assertSentWithXMLFormDataAccept(MockWebServer server, String method, String path, - String body, String acceptType) throws InterruptedException { - - RecordedRequest request = server.takeRequest(); - assertThat(request.getMethod()).isEqualTo(method); - assertThat(request.getPath()).isEqualTo(path); - assertThat(request.getUtf8Body()).isEqualTo(body); - assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(acceptType); - assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo(MediaType.APPLICATION_XML); - return request; - } - - protected RecordedRequest assertSentAcceptText(MockWebServer server, String method, String path) throws InterruptedException { - RecordedRequest request = server.takeRequest(); - assertThat(request.getMethod()).isEqualTo(method); - assertThat(request.getPath()).isEqualTo(path); - assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.TEXT_PLAIN); - return request; - } - - protected RecordedRequest assertSentAccept(MockWebServer server, String method, String path, String acceptType) throws InterruptedException { - RecordedRequest request = server.takeRequest(); - assertThat(request.getMethod()).isEqualTo(method); - assertThat(request.getPath()).isEqualTo(path); - assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(acceptType); - return request; - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/JenkinsApiMetadataTest.java b/src/test/java/com/cdancy/jenkins/rest/JenkinsApiMetadataTest.java deleted file mode 100644 index d33952c..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/JenkinsApiMetadataTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest; - -import org.jclouds.apis.ApiMetadata; -import org.jclouds.apis.Apis; -import org.jclouds.apis.internal.BaseApiMetadataTest; -import org.testng.annotations.Test; - -import java.util.HashSet; - -import static org.testng.Assert.*; - -/** - * Unit tests for the {@link JenkinsApiMetadata} class. - */ -@Test(groups = "unit", testName = "JenkinsApiMetadataTest") -public class JenkinsApiMetadataTest extends BaseApiMetadataTest { - - public JenkinsApiMetadataTest() { - super(new JenkinsApiMetadata(), new HashSet<>()); - } - - public void testEtcdApiRegistered() { - ApiMetadata api = Apis.withId("jenkins"); - - assertNotNull(api); - assertTrue(api instanceof JenkinsApiMetadata); - assertEquals(api.getId(), "jenkins"); - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/JenkinsAuthenticationMockTest.java b/src/test/java/com/cdancy/jenkins/rest/JenkinsAuthenticationMockTest.java deleted file mode 100644 index 82275e4..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/JenkinsAuthenticationMockTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest; - -import com.cdancy.jenkins.rest.auth.AuthenticationType; -import com.cdancy.jenkins.rest.exception.UndetectableIdentityException; -import org.testng.annotations.Test; - -import static com.google.common.io.BaseEncoding.base64; -import static org.testng.Assert.assertEquals; - -public class JenkinsAuthenticationMockTest { - - @Test - public void testAnonymousAuthentication() { - JenkinsAuthentication ja = JenkinsAuthentication.builder().build(); - assertEquals(ja.identity, "anonymous"); - assertEquals(ja.authType(), AuthenticationType.Anonymous); - assertEquals(ja.authValue(), base64().encode("anonymous:".getBytes())); - assertEquals(ja.credential, ja.authValue()); - } - - @Test - public void testUsernamePasswordAuthentication() { - JenkinsAuthentication ja = JenkinsAuthentication.builder() - .credentials("user:password") - .build(); - assertEquals(ja.identity, "user"); - assertEquals(ja.authType(), AuthenticationType.UsernamePassword); - assertEquals(ja.authValue(), base64().encode("user:password".getBytes())); - assertEquals(ja.credential, ja.authValue()); - } - - @Test - public void testUsernameApiTokenAuthentication() { - JenkinsAuthentication ja = JenkinsAuthentication.builder() - .apiToken("user:token") - .build(); - assertEquals(ja.identity, "user"); - assertEquals(ja.authType(), AuthenticationType.UsernameApiToken); - assertEquals(ja.authValue(), base64().encode("user:token".getBytes())); - assertEquals(ja.credential, ja.authValue()); - } - - @Test - public void testEncodedUsernamePasswordAuthentication() { - String encoded = base64().encode("user:password".getBytes()); - JenkinsAuthentication ja = JenkinsAuthentication.builder() - .credentials(encoded) - .build(); - assertEquals(ja.identity, "user"); - assertEquals(ja.authType(), AuthenticationType.UsernamePassword); - assertEquals(ja.authValue(), encoded); - assertEquals(ja.credential, ja.authValue()); - } - - @Test - public void testEncodedUsernameApiTokenAuthentication() { - String encoded = base64().encode("user:token".getBytes()); - JenkinsAuthentication ja = JenkinsAuthentication.builder() - .apiToken(encoded) - .build(); - assertEquals(ja.identity, "user"); - assertEquals(ja.authType(), AuthenticationType.UsernameApiToken); - assertEquals(ja.authValue(), encoded); - assertEquals(ja.credential, ja.authValue()); - } - - @Test - public void testEmptyUsernamePassword() { - JenkinsAuthentication ja = JenkinsAuthentication.builder() - .credentials(":") - .build(); - assertEquals(ja.identity, ""); - assertEquals(ja.authType(), AuthenticationType.UsernamePassword); - assertEquals(ja.authValue(), base64().encode(":".getBytes())); - assertEquals(ja.credential, ja.authValue()); - } - - @Test - public void testEmptyUsernameApiToken() { - JenkinsAuthentication ja = JenkinsAuthentication.builder() - .apiToken(":") - .build(); - assertEquals(ja.identity, ""); - assertEquals(ja.authType(), AuthenticationType.UsernameApiToken); - assertEquals(ja.authValue(), base64().encode(":".getBytes())); - assertEquals(ja.credential, ja.authValue()); - } - - @Test - public void testUndetectableCredential() { - String invalid = base64().encode("no_colon_here".getBytes()); - try { - JenkinsAuthentication.builder() - .apiToken(invalid) - .build(); - } catch (UndetectableIdentityException ex) { - assertEquals(ex.getMessage(), - "Unable to detect the identity being used in '" + invalid + "'. Supported types are a user:password, or a user:apiToken, or their base64 encoded value."); - } - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApiMockTest.java b/src/test/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApiMockTest.java deleted file mode 100644 index bf80e09..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApiMockTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import static org.testng.Assert.*; - -/** - * Mock tests for the {@link com.cdancy.jenkins.rest.features.ConfigurationAsCodeApi} class. - */ -@Test(groups = "unit", testName = "ConfigurationAsCodeApiMockTest") -public class ConfigurationAsCodeApiMockTest extends BaseJenkinsMockTest { - - public void testCascCheck() throws Exception { - try (MockWebServer server = mockWebServer(); - JenkinsApi jenkinsApi = api(server.url("/").url())) { - server.enqueue(new MockResponse().setResponseCode(200)); - - ConfigurationAsCodeApi api = jenkinsApi.configurationAsCodeApi(); - RequestStatus requestStatus = api.check("random"); - System.out.println(requestStatus.errors()); - assertNotNull(requestStatus); - assertTrue(requestStatus.value()); - assertEquals(requestStatus.errors().size(), 0); - } - } - - public void testCascApply() throws Exception { - try (MockWebServer server = mockWebServer(); - JenkinsApi jenkinsApi = api(server.url("/").url())) { - server.enqueue(new MockResponse().setResponseCode(200)); - - ConfigurationAsCodeApi api = jenkinsApi.configurationAsCodeApi(); - RequestStatus requestStatus = api.apply("random"); - assertNotNull(requestStatus); - assertTrue(requestStatus.value()); - assertEquals(requestStatus.errors().size(), 0); - } - } - - public void testBadCascCheck() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(500)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - ConfigurationAsCodeApi api = jenkinsApi.configurationAsCodeApi(); - try { - RequestStatus requestStatus = api.check("random"); - assertNotNull(requestStatus); - assertFalse(requestStatus.value()); - assertEquals(requestStatus.errors().size(), 1); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testBadCascApply() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(500)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - ConfigurationAsCodeApi api = jenkinsApi.configurationAsCodeApi(); - try { - RequestStatus requestStatus = api.apply("random"); - assertNotNull(requestStatus); - assertFalse(requestStatus.value()); - assertEquals(requestStatus.errors().size(), 1); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/CrumbIssuerApiMockTest.java b/src/test/java/com/cdancy/jenkins/rest/features/CrumbIssuerApiMockTest.java deleted file mode 100644 index 43bec78..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/CrumbIssuerApiMockTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; -import com.cdancy.jenkins.rest.domain.crumb.Crumb; - -import javax.ws.rs.core.MediaType; - -import static org.testng.Assert.*; - -/** - * Mock tests for the {@link com.cdancy.jenkins.rest.features.CrumbIssuerApi} class. - */ -@Test(groups = "unit", testName = "CrumbIssuerApiMockTest") -public class CrumbIssuerApiMockTest extends BaseJenkinsMockTest { - - public void testGetSystemInfo() throws Exception { - MockWebServer server = mockWebServer(); - - final String value = "04a1109fc2db171362c966ebe9fc87f0"; - server.enqueue(new MockResponse().setBody("Jenkins-Crumb:" + value).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - CrumbIssuerApi api = jenkinsApi.crumbIssuerApi(); - try { - final Crumb instance = api.crumb(); - assertNotNull(instance); - assertEquals(instance.value(), value); - assertSentAccept(server, "GET", "/crumbIssuer/api/xml?xpath=concat%28//crumbRequestField,%22%3A%22,//crumb%29", MediaType.TEXT_PLAIN); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/JobsApiLiveTest.java b/src/test/java/com/cdancy/jenkins/rest/features/JobsApiLiveTest.java deleted file mode 100644 index 61a7648..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/JobsApiLiveTest.java +++ /dev/null @@ -1,685 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest; -import com.cdancy.jenkins.rest.domain.common.IntegerResponse; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.job.*; -import com.cdancy.jenkins.rest.domain.plugins.Plugin; -import com.cdancy.jenkins.rest.domain.plugins.Plugins; -import com.cdancy.jenkins.rest.domain.queue.QueueItem; -import com.google.common.collect.Lists; -import org.testng.annotations.Test; - -import static org.testng.Assert.*; - -@Test(groups = "live", testName = "JobsApiLiveTest", singleThreaded = true) -public class JobsApiLiveTest extends BaseJenkinsApiLiveTest { - - private IntegerResponse queueId; - private IntegerResponse queueIdForAnotherJob; - private Integer buildNumber; - private static final String FOLDER_PLUGIN_NAME = "cloudbees-folder"; - private static final String FOLDER_PLUGIN_VERSION = "latest"; - - private static final String FREESTYLE_JOB_NAME = "FreeStyleSleep"; - private static final String PIPELINE_JOB_NAME = "PipelineSleep"; - private static final String PIPELINE_WITH_ACTION_JOB_NAME = "PipelineAction"; - - @Test - public void testCreateJob() { - String config = payloadFromResource("/freestyle-project-no-params.xml"); - RequestStatus success = api().create(null, "DevTest", config); - assertTrue(success.value()); - } - - // The next 3 tests must run one after the other as they use the same Job - @Test - public void testStopFreeStyleBuild() throws InterruptedException { - String config = payloadFromResource("/freestyle-project-sleep-10-task.xml"); - RequestStatus createStatus = api().create(null, FREESTYLE_JOB_NAME, config); - assertTrue(createStatus.value()); - IntegerResponse qId = api().build(null, FREESTYLE_JOB_NAME); - assertNotNull(qId); - assertTrue(qId.value() > 0); - QueueItem queueItem = getRunningQueueItem(qId.value()); - assertNotNull(queueItem); - assertNotNull(queueItem.executable()); - assertNotNull(queueItem.executable().number()); - RequestStatus stopStatus = api().stop(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); - assertTrue(stopStatus.value()); - BuildInfo buildInfo = getCompletedBuild(FREESTYLE_JOB_NAME, queueItem); - assertEquals(buildInfo.result(), "ABORTED"); - } - - @Test(dependsOnMethods = "testStopFreeStyleBuild") - public void testTermFreeStyleBuild() throws InterruptedException { - IntegerResponse qId = api().build(null, FREESTYLE_JOB_NAME); - assertNotNull(qId); - assertTrue(qId.value() > 0); - QueueItem queueItem = getRunningQueueItem(qId.value()); - assertNotNull(queueItem); - assertNotNull(queueItem.executable()); - assertNotNull(queueItem.executable().number()); - RequestStatus termStatus = api().term(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); - // Strangely, term does not work on FreeStyleBuild - assertFalse(termStatus.value()); - assertEquals(termStatus.errors().size(), 1); - assertEquals(termStatus.errors().get(0).message(), "The term operation does not exist for " + - System.getProperty("test.jenkins.endpoint") + - "/job/"+FREESTYLE_JOB_NAME+"/"+queueItem.executable().number()+"/term/, try stop instead."); - assertEquals(termStatus.errors().get(0).exceptionName(), "com.cdancy.jenkins.rest.exception.RedirectTo404Exception"); - api().stop(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); - BuildInfo buildInfoStop = getCompletedBuild(FREESTYLE_JOB_NAME, queueItem); - assertEquals(buildInfoStop.result(), "ABORTED"); - } - - @Test(dependsOnMethods = "testTermFreeStyleBuild") - public void testKillFreeStyleBuild() throws InterruptedException { - IntegerResponse qId = api().build(null, FREESTYLE_JOB_NAME); - assertNotNull(qId); - assertTrue(qId.value() > 0); - QueueItem queueItem = getRunningQueueItem(qId.value()); - assertNotNull(queueItem); - assertNotNull(queueItem.executable()); - assertNotNull(queueItem.executable().number()); - RequestStatus killStatus = api().kill(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); - // Strangely, kill does not work on FreeStyleBuild - assertFalse(killStatus.value()); - assertEquals(killStatus.errors().size(), 1); - assertEquals(killStatus.errors().get(0).message(), "The kill operation does not exist for " + - System.getProperty("test.jenkins.endpoint") + - "/job/"+FREESTYLE_JOB_NAME+"/"+queueItem.executable().number()+"/kill/, try stop instead."); - assertEquals(killStatus.errors().get(0).exceptionName(), "com.cdancy.jenkins.rest.exception.RedirectTo404Exception"); - api().stop(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); - BuildInfo buildInfoStop = getCompletedBuild(FREESTYLE_JOB_NAME, queueItem); - assertEquals(buildInfoStop.result(), "ABORTED"); - - // Delete the job, it's no longer needed - RequestStatus success = api().delete(null, FREESTYLE_JOB_NAME); - assertNotNull(success); - assertTrue(success.value()); - } - - // The next 3 tests must run one after the other as they use the same Job - @Test - public void testStopPipelineBuild() throws InterruptedException { - String config = payloadFromResource("/pipeline.xml"); - RequestStatus createStatus = api().create(null, PIPELINE_JOB_NAME, config); - assertTrue(createStatus.value()); - IntegerResponse qId = api().build(null, PIPELINE_JOB_NAME); - assertNotNull(qId); - assertTrue(qId.value() > 0); - QueueItem queueItem = getRunningQueueItem(qId.value()); - assertNotNull(queueItem); - assertNotNull(queueItem.executable()); - assertNotNull(queueItem.executable().number()); - RequestStatus stopStatus = api().stop(null, PIPELINE_JOB_NAME, queueItem.executable().number()); - assertTrue(stopStatus.value()); - BuildInfo buildInfo = getCompletedBuild(PIPELINE_JOB_NAME, queueItem); - assertEquals(buildInfo.result(), "ABORTED"); - } - - @Test(dependsOnMethods = "testStopPipelineBuild") - public void testTermPipelineBuild() throws InterruptedException { - IntegerResponse qId = api().build(null, PIPELINE_JOB_NAME); - assertNotNull(qId); - assertTrue(qId.value() > 0); - QueueItem queueItem = getRunningQueueItem(qId.value()); - assertNotNull(queueItem); - assertNotNull(queueItem.executable()); - assertNotNull(queueItem.executable().number()); - RequestStatus termStatus = api().term(null, PIPELINE_JOB_NAME, queueItem.executable().number()); - assertTrue(termStatus.value()); - BuildInfo buildInfo = getCompletedBuild(PIPELINE_JOB_NAME, queueItem); - assertEquals(buildInfo.result(), "ABORTED"); - } - - @Test(dependsOnMethods = "testTermPipelineBuild") - public void testKillPipelineBuild() throws InterruptedException { - IntegerResponse qId = api().build(null, PIPELINE_JOB_NAME); - assertNotNull(qId); - assertTrue(qId.value() > 0); - QueueItem queueItem = getRunningQueueItem(qId.value()); - assertNotNull(queueItem); - assertNotNull(queueItem.executable()); - assertNotNull(queueItem.executable().number()); - RequestStatus killStatus = api().kill(null, PIPELINE_JOB_NAME, queueItem.executable().number()); - assertTrue(killStatus.value()); - BuildInfo buildInfo = getCompletedBuild(PIPELINE_JOB_NAME, queueItem); - assertEquals(buildInfo.result(), "ABORTED"); - - // The Job is no longer needed, delete it. - RequestStatus success = api().delete(null, PIPELINE_JOB_NAME); - assertNotNull(success); - assertTrue(success.value()); - } - - @Test(dependsOnMethods = {"testCreateJob", "testCreateJobForEmptyAndNullParams", "testKillPipelineBuild", "testKillFreeStyleBuild", "testDeleteFolders"}) - public void testGetJobListFromRoot() { - JobList output = api().jobList(""); - assertNotNull(output); - assertFalse(output.jobs().isEmpty()); - assertEquals(output.jobs().size(), 2); - } - - @Test(dependsOnMethods = "testCreateJob") - public void testGetJobInfo() { - JobInfo output = api().jobInfo(null, "DevTest"); - assertNotNull(output); - assertEquals(output.name(), "DevTest"); - assertNull(output.lastBuild()); - assertNull(output.firstBuild()); - assertTrue(output.builds().isEmpty()); - } - - @Test(dependsOnMethods = "testGetJobInfo") - public void testLastBuildNumberOnJobWithNoBuilds() { - Integer output = api().lastBuildNumber(null, "DevTest"); - assertNull(output); - } - - @Test(dependsOnMethods = "testLastBuildNumberOnJobWithNoBuilds") - public void testLastBuildTimestampOnJobWithNoBuilds() { - String output = api().lastBuildTimestamp(null, "DevTest"); - assertNull(output); - } - - @Test(dependsOnMethods = "testLastBuildTimestampOnJobWithNoBuilds") - public void testBuildJob() throws InterruptedException { - queueId = api().build(null, "DevTest"); - assertNotNull(queueId); - assertTrue(queueId.value() > 0); - assertEquals(queueId.errors().size(), 0); - // Before we exit the test, wait until the job runs - QueueItem queueItem = getRunningQueueItem(queueId.value()); - getCompletedBuild("DevTest", queueItem); - } - - @Test(dependsOnMethods = "testBuildJob") - public void testLastBuildNumberOnJob() { - buildNumber = api().lastBuildNumber(null, "DevTest"); - assertNotNull(buildNumber); - assertEquals((int) buildNumber, 1); - } - - @Test(dependsOnMethods = "testLastBuildNumberOnJob") - public void testLastBuildTimestamp() { - String output = api().lastBuildTimestamp(null, "DevTest"); - assertNotNull(output); - } - - @Test(dependsOnMethods = "testLastBuildTimestamp") - public void testLastBuildGetProgressiveText() { - ProgressiveText output = api().progressiveText(null, "DevTest", 0); - assertNotNull(output); - assertTrue(output.size() > 0); - assertFalse(output.hasMoreData()); - } - - @Test(dependsOnMethods = "testLastBuildGetProgressiveText") - public void testGetBuildInfo() { - BuildInfo output = api().buildInfo(null, "DevTest", buildNumber); - assertNotNull(output); - assertEquals("DevTest #" + buildNumber, output.fullDisplayName()); - assertEquals((int) queueId.value(), output.queueId()); - } - - @Test(dependsOnMethods = "testGetBuildInfo") - public void testGetBuildParametersOfLastJob() { - List parameters = api().buildInfo(null, "DevTest", 1).actions().get(0).parameters(); - assertEquals(parameters.size(), 0); - } - - @Test - public void testBuildInfoActions() throws InterruptedException { - String config = payloadFromResource("/pipeline-with-action.xml"); - RequestStatus createStatus = api().create(null, PIPELINE_WITH_ACTION_JOB_NAME, config); - assertTrue(createStatus.value()); - IntegerResponse qId = api().build(null, PIPELINE_WITH_ACTION_JOB_NAME); - assertNotNull(qId); - assertTrue(qId.value() > 0); - QueueItem queueItem = getRunningQueueItem(qId.value()); - assertNotNull(queueItem); - assertNotNull(queueItem.executable()); - assertNotNull(queueItem.executable().number()); - BuildInfo buildInfo = getCompletedBuild(PIPELINE_WITH_ACTION_JOB_NAME, queueItem); - assertEquals(buildInfo.result(), "SUCCESS"); - System.out.println(buildInfo); - boolean found = false; - for (int idx = 0; idx < buildInfo.actions().size(); idx++) { - if (buildInfo.actions().get(idx).text() != null) { - if (buildInfo.actions().get(idx).text().equals("Hudson, we have a problem.") && - buildInfo.actions().get(idx).iconPath().equals("error.svg") && - buildInfo.actions().get(idx)._class().equals("com.jenkinsci.plugins.badge.action.BadgeSummaryAction")) { - found = true; - } - } - } - assertTrue(found); - - // The Job is no longer needed, delete it. - RequestStatus success = api().delete(null, PIPELINE_WITH_ACTION_JOB_NAME); - assertNotNull(success); - assertTrue(success.value()); - } - - @Test(dependsOnMethods = "testGetBuildParametersOfLastJob") - public void testCreateJobThatAlreadyExists() { - String config = payloadFromResource("/freestyle-project.xml"); - RequestStatus success = api().create(null, "DevTest", config); - assertFalse(success.value()); - } - - @Test(dependsOnMethods = "testCreateJobThatAlreadyExists") - public void testSetDescription() { - boolean success = api().description(null, "DevTest", "RandomDescription"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testSetDescription") - public void testGetDescription() { - String output = api().description(null, "DevTest"); - assertEquals(output, "RandomDescription"); - } - - @Test(dependsOnMethods = "testGetDescription") - public void testGetConfig() { - String output = api().config(null, "DevTest"); - assertNotNull(output); - } - - @Test(dependsOnMethods = "testGetConfig") - public void testUpdateConfig() { - String config = payloadFromResource("/freestyle-project.xml"); - boolean success = api().config(null, "DevTest", config); - assertTrue(success); - } - - @Test(dependsOnMethods = "testUpdateConfig") - public void testBuildJobWithParameters() { - Map> params = new HashMap<>(); - params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); - IntegerResponse output = api().buildWithParameters(null, "DevTest", params); - assertNotNull(output); - assertTrue(output.value() > 0); - assertEquals(output.errors().size(), 0); - } - - @Test(dependsOnMethods = "testBuildJobWithParameters") - public void testBuildJobWithNullParametersMap() { - IntegerResponse output = api().buildWithParameters(null, "DevTest", null); - assertNotNull(output); - assertTrue(output.value() > 0); - assertEquals(output.errors().size(), 0); - } - - @Test(dependsOnMethods = "testBuildJobWithNullParametersMap") - public void testBuildJobWithEmptyParametersMap() { - IntegerResponse output = api().buildWithParameters(null, "DevTest", new HashMap<>()); - assertNotNull(output); - assertNull(output.value()); - assertEquals(output.errors().size(), 1); - } - - @Test(dependsOnMethods = "testBuildJobWithEmptyParametersMap") - public void testDisableJob() { - boolean success = api().disable(null, "DevTest"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testDisableJob") - public void testDisableJobAlreadyDisabled() { - boolean success = api().disable(null, "DevTest"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testDisableJobAlreadyDisabled") - public void testEnableJob() { - boolean success = api().enable(null, "DevTest"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testEnableJob") - public void testEnableJobAlreadyEnabled() { - boolean success = api().enable(null, "DevTest"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testEnableJobAlreadyEnabled") - public void testRenameJob(){ - boolean success = api().rename(null,"DevTest","NewDevTest"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testRenameJob") - public void testRenameJobNotExist(){ - boolean success = api().rename(null,"JobNotExist","NewDevTest"); - assertFalse(success); - } - - @Test(dependsOnMethods = "testRenameJobNotExist") - public void testDeleteJob() { - RequestStatus success = api().delete(null, "NewDevTest"); - assertNotNull(success); - assertTrue(success.value()); - } - - // - // check for the presence of folder-plugin - // If not present, attempt to install it. - // - @Test - public void testInstallFolderPlugin() throws Exception{ - long endTime = 0; - long maxWaitTime = 5 * 60 * 1000; - if(!isFolderPluginInstalled()) { - RequestStatus status = api.pluginManagerApi().installNecessaryPlugins(FOLDER_PLUGIN_NAME + "@" + FOLDER_PLUGIN_VERSION); - assertTrue(status.value()); - while(endTime <= maxWaitTime) { - if(!isFolderPluginInstalled()) { - Thread.sleep(10000); - endTime += 10000; - } else { - break; - } - } - } - assertTrue(isFolderPluginInstalled()); - } - - @Test(dependsOnMethods = "testInstallFolderPlugin") - public void testCreateFoldersInJenkins() { - String config = payloadFromResource("/folder-config.xml"); - RequestStatus success1 = api().create(null, "test-folder", config); - assertTrue(success1.value()); - RequestStatus success2 = api().create("test-folder", "test-folder-1", config); - assertTrue(success2.value()); - } - - @Test(dependsOnMethods = "testCreateFoldersInJenkins") - public void testCreateJobInFolder() { - String config = payloadFromResource("/freestyle-project-no-params.xml"); - RequestStatus success = api().create("test-folder/test-folder-1", "JobInFolder", config); - assertTrue(success.value()); - } - - @Test(dependsOnMethods = "testCreateFoldersInJenkins") - public void testCreateJobWithIncorrectFolderPath() { - String config = payloadFromResource("/folder-config.xml"); - RequestStatus success = api().create("/test-folder//test-folder-1/", "Job",config); - assertFalse(success.value()); - } - - @Test(dependsOnMethods = "testCreateJobInFolder") - public void testGetJobListInFolder() { - JobList output = api().jobList("test-folder/test-folder-1"); - assertNotNull(output); - assertFalse(output.jobs().isEmpty()); - assertEquals(output.jobs().size(), 1); - assertEquals(output.jobs().get(0), Job.create("hudson.model.FreeStyleProject", "JobInFolder", System.getProperty("test.jenkins.endpoint")+"/job/test-folder/job/test-folder-1/job/JobInFolder/", "notbuilt")); - } - - @Test(dependsOnMethods = "testCreateJobInFolder") - public void testUpdateJobConfigInFolder() { - String config = payloadFromResource("/freestyle-project.xml"); - boolean success = api().config("test-folder/test-folder-1", "JobInFolder", config); - assertTrue(success); - } - - @Test(dependsOnMethods = "testUpdateJobConfigInFolder") - public void testDisableJobInFolder() { - boolean success = api().disable("test-folder/test-folder-1", "JobInFolder"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testDisableJobInFolder") - public void testEnableJobInFolder() { - boolean success = api().enable("test-folder/test-folder-1", "JobInFolder"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testEnableJobInFolder") - public void testSetDescriptionOfJobInFolder() { - boolean success = api().description("test-folder/test-folder-1", "JobInFolder", "RandomDescription"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testSetDescriptionOfJobInFolder") - public void testGetDescriptionOfJobInFolder() { - String output = api().description("test-folder/test-folder-1", "JobInFolder"); - assertEquals(output, "RandomDescription"); - } - - @Test(dependsOnMethods = "testGetDescriptionOfJobInFolder") - public void testGetJobInfoInFolder() { - JobInfo output = api().jobInfo("test-folder/test-folder-1", "JobInFolder"); - assertNotNull(output); - assertEquals(output.name(), "JobInFolder"); - assertTrue(output.builds().isEmpty()); - } - - @Test(dependsOnMethods = "testGetJobInfoInFolder") - public void testBuildWithParameters() throws InterruptedException { - Map> params = new HashMap<>(); - params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); - queueIdForAnotherJob = api().buildWithParameters("test-folder/test-folder-1", "JobInFolder", params); - assertNotNull(queueIdForAnotherJob); - assertTrue(queueIdForAnotherJob.value() > 0); - QueueItem queueItem = getRunningQueueItem(queueIdForAnotherJob.value()); - assertNotNull(queueItem); - } - - @Test(dependsOnMethods = "testBuildWithParameters") - public void testLastBuildTimestampOfJobInFolder() { - String output = api().lastBuildTimestamp("test-folder/test-folder-1", "JobInFolder"); - assertNotNull(output); - } - - @Test(dependsOnMethods = "testLastBuildTimestampOfJobInFolder") - public void testGetProgressiveText() { - ProgressiveText output = api().progressiveText("test-folder/test-folder-1", "JobInFolder", 0); - assertNotNull(output); - assertTrue(output.size() > 0); - assertFalse(output.hasMoreData()); - } - - @Test(dependsOnMethods = "testGetProgressiveText") - public void testGetBuildInfoOfJobInFolder() { - BuildInfo output = api().buildInfo("test-folder/test-folder-1", "JobInFolder", 1); - assertNotNull(output); - assertTrue(output.fullDisplayName().contains("JobInFolder #1")); - assertEquals((int) queueIdForAnotherJob.value(), output.queueId()); - } - - @Test(dependsOnMethods = "testGetProgressiveText") - public void testGetBuildParametersofJob() { - List parameters = api().buildInfo("test-folder/test-folder-1", "JobInFolder",1).actions().get(0).parameters(); - assertNotNull(parameters); - assertEquals(parameters.get(0).name(), "SomeKey"); - assertEquals(parameters.get(0).value(), "SomeVeryNewValue"); - } - - @Test(dependsOnMethods = "testGetProgressiveText") - public void testGetBuildCausesOfJob() { - List causes = api().buildInfo("test-folder/test-folder-1", "JobInFolder",1).actions().get(1).causes(); - assertNotNull(causes); - assertTrue(causes.size() > 0); - assertNotNull(causes.get(0).shortDescription()); - assertNotNull(causes.get(0).userId()); - assertNotNull(causes.get(0).userName()); - } - - @Test(dependsOnMethods = "testGetProgressiveText") - public void testGetProgressiveTextOfBuildNumber() { - ProgressiveText output = api().progressiveText("test-folder/test-folder-1", "JobInFolder", 1,0); - assertNotNull(output); - assertTrue(output.size() > 0); - assertFalse(output.hasMoreData()); - } - - @Test - public void testCreateJobForEmptyAndNullParams() { - String config = payloadFromResource("/freestyle-project-empty-and-null-params.xml"); - RequestStatus success = api().create(null, "JobForEmptyAndNullParams", config); - assertTrue(success.value()); - } - - @Test(dependsOnMethods = "testCreateJobForEmptyAndNullParams") - public void testBuildWithParametersOfJobForEmptyAndNullParams() throws InterruptedException { - Map> params = new HashMap<>(); - params.put("SomeKey1", Lists.newArrayList("")); - params.put("SomeKey2", null); - IntegerResponse job1 = api.jobsApi().buildWithParameters(null, "JobForEmptyAndNullParams", params); - assertNotNull(job1); - assertTrue(job1.value() > 0); - assertEquals(job1.errors().size(), 0); - QueueItem queueItem = getRunningQueueItem(job1.value()); - assertNotNull(queueItem); - } - - @Test(dependsOnMethods = "testBuildWithParametersOfJobForEmptyAndNullParams") - public void testGetBuildParametersOfJobForEmptyAndNullParams() { - List parameters = api().buildInfo(null, "JobForEmptyAndNullParams", 1).actions().get(0).parameters(); - assertNotNull(parameters); - assertEquals(parameters.get(0).name(), "SomeKey1"); - assertTrue(parameters.get(0).value().isEmpty()); - assertEquals(parameters.get(1).name(), "SomeKey2"); - assertTrue(parameters.get(1).value().isEmpty()); - } - - @Test(dependsOnMethods = { "testGetBuildParametersOfJobForEmptyAndNullParams", "testGetJobListFromRoot"}) - public void testDeleteJobForEmptyAndNullParams() { - RequestStatus success = api().delete(null, "JobForEmptyAndNullParams"); - assertTrue(success.value()); - } - - @Test(dependsOnMethods = "testCreateFoldersInJenkins") - public void testCreateJobWithLeadingAndTrailingForwardSlashes() { - String config = payloadFromResource("/freestyle-project-no-params.xml"); - RequestStatus success = api().create("/test-folder/test-folder-1/", "Job", config); - assertTrue(success.value()); - } - - @Test(dependsOnMethods = "testCreateJobWithLeadingAndTrailingForwardSlashes") - public void testDeleteJobWithLeadingAndTrailingForwardSlashes() { - RequestStatus success = api().delete("/test-folder/test-folder-1/", "Job"); - assertTrue(success.value()); - } - - @Test(dependsOnMethods = "testGetBuildInfoOfJobInFolder") - public void testRenameJonInFloder(){ - boolean success = api().rename("test-folder/test-folder-1", "JobInFolder", "NewJobInFolder"); - assertTrue(success); - } - - @Test(dependsOnMethods = "testRenameJonInFloder") - public void testDeleteJobInFolder() { - RequestStatus success = api().delete("test-folder/test-folder-1", "NewJobInFolder"); - assertTrue(success.value()); - } - - @Test(dependsOnMethods = "testDeleteJobInFolder") - public void testDeleteFolders() { - RequestStatus success1 = api().delete("test-folder", "test-folder-1"); - assertTrue(success1.value()); - RequestStatus success2 = api().delete(null, "test-folder"); - assertTrue(success2.value()); - } - - @Test - public void testGetJobInfoNonExistentJob() { - JobInfo output = api().jobInfo(null, randomString()); - assertNull(output); - } - - @Test - public void testDeleteJobNonExistent() { - RequestStatus success = api().delete(null, randomString()); - assertNotNull(success); - assertFalse(success.value()); - } - - @Test - public void testGetConfigNonExistentJob() { - String output = api().config(null, randomString()); - assertNull(output); - } - - @Test - public void testSetDescriptionNonExistentJob() { - boolean success = api().description(null, randomString(), "RandomDescription"); - assertFalse(success); - } - - @Test - public void testGetDescriptionNonExistentJob() { - String output = api().description(null, randomString()); - assertNull(output); - } - - @Test - public void testBuildNonExistentJob() { - IntegerResponse output = api().build(null, randomString()); - assertNotNull(output); - assertNull(output.value()); - assertTrue(output.errors().size() > 0); - assertNotNull(output.errors().get(0).context()); - assertNotNull(output.errors().get(0).message()); - assertEquals(output.errors().get(0).exceptionName(), "org.jclouds.rest.ResourceNotFoundException"); - } - - @Test - public void testGetBuildInfoNonExistentJob() { - BuildInfo output = api().buildInfo(null, randomString(), 123); - assertNull(output); - } - - @Test - public void testBuildNonExistentJobWithParams() { - Map> params = new HashMap<>(); - params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); - IntegerResponse output = api().buildWithParameters(null, randomString(), params); - assertNotNull(output); - assertNull(output.value()); - assertTrue(output.errors().size() > 0); - assertNotNull(output.errors().get(0).context()); - assertNotNull(output.errors().get(0).message()); - assertEquals(output.errors().get(0).exceptionName(), "org.jclouds.rest.ResourceNotFoundException"); - } - - private boolean isFolderPluginInstalled() { - boolean installed = false; - Plugins plugins = api.pluginManagerApi().plugins(3, null); - for(Plugin plugin:plugins.plugins()) { - if(plugin.shortName().equals(FOLDER_PLUGIN_NAME)) { - installed = true; - break; - } - } - return installed; - } - - private JobsApi api() { - return api.jobsApi(); - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/JobsApiMockTest.java b/src/test/java/com/cdancy/jenkins/rest/features/JobsApiMockTest.java deleted file mode 100644 index a078884..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/JobsApiMockTest.java +++ /dev/null @@ -1,1139 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.domain.common.IntegerResponse; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.job.*; -import com.google.common.collect.Lists; -import com.google.gson.JsonObject; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import javax.ws.rs.core.MediaType; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.testng.Assert.*; - -/** - * Mock tests for the {@link com.cdancy.jenkins.rest.features.JobsApi} class. - */ -@Test(groups = "unit", testName = "JobsApiMockTest") -public class JobsApiMockTest extends BaseJenkinsMockTest { - - public void testGetInnerFolderJobList() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/jobsInJenkinsFolder.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - JobList output = api.jobList("Folder1/Folder 2"); - assertNotNull(output); - assertNotNull(output.jobs()); - assertEquals(output.jobs().size(), 1); - assertEquals(output.jobs().get(0), Job.create("hudson.model.FreeStyleProject", "Test Project", "http://localhost:8080/job/username", null)); - assertSent(server, "GET", "/job/Folder1/job/Folder%202/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetRootFolderJobList() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/jobsInRootFolder.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - JobList output = api.jobList(""); - assertNotNull(output); - assertNotNull(output.jobs()); - assertEquals(output.jobs().size(), 6); - assertSent(server, "GET", "/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetJobInfo() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/job-info.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - JobInfo output = api.jobInfo(null,"fish"); - assertNotNull(output); - assertEquals(output.name(), "fish"); - assertEquals(output.builds().size(), 7); - assertSent(server, "GET", "/job/fish/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetJobInfoNotFound() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - JobInfo output = api.jobInfo(null,"fish"); - assertNull(output); - assertSent(server, "GET", "/job/fish/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetBuildInfo() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/build-info.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - BuildInfo output = api.buildInfo(null,"fish", 10); - assertNotNull(output); - assertEquals(output.fullDisplayName(), "fish #10"); - assertEquals(output.artifacts().size(), 1); - assertEquals(output.actions().size(), 5); - assertEquals(output.actions().get(2).text(), "There could be HTML text here"); - assertEquals(output.actions().get(2).iconPath(), "clipboard.png"); - assertEquals(output.actions().get(2)._class(), "com.jenkinsci.plugins.badge.action.BadgeSummaryAction"); - assertEquals(output.actions().get(3).text(), null); - assertEquals(output.actions().get(4)._class(), "org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction"); - assertSent(server, "GET", "/job/fish/10/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetBuildInfoNotFound() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - BuildInfo output = api.buildInfo(null,"fish", 10); - assertNull(output); - assertSent(server, "GET", "/job/fish/10/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testCreateJob() throws Exception { - MockWebServer server = mockWebServer(); - - String configXML = payloadFromResource("/freestyle-project.xml"); - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus success = api.create(null, "DevTest", configXML); - assertNotNull(success); - assertTrue(success.value()); - assertTrue(success.errors().isEmpty()); - assertSentWithXMLFormDataAccept(server, "POST", "/createItem?name=DevTest", configXML, MediaType.WILDCARD); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testCreateJobInFolder() throws Exception { - MockWebServer server = mockWebServer(); - - String configXML = payloadFromResource("/freestyle-project.xml"); - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus success = api.create("test-folder", "JobInFolder", configXML); - assertNotNull(success); - assertTrue(success.value()); - assertTrue(success.errors().isEmpty()); - assertSentWithXMLFormDataAccept(server, "POST", "/job/test-folder/createItem?name=JobInFolder", configXML, MediaType.WILDCARD); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testSimpleFolderPathWithLeadingAndTrailingForwardSlashes() throws Exception { - MockWebServer server = mockWebServer(); - - String configXML = payloadFromResource("/freestyle-project.xml"); - server.enqueue(new MockResponse().setResponseCode(200)); - - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus success = api.create("/test-folder/test-folder-1/", "JobInFolder", configXML); - assertNotNull(success); - assertTrue(success.value()); - assertTrue(success.errors().isEmpty()); - assertSentWithXMLFormDataAccept(server, "POST", "/job/test-folder/job/test-folder-1/createItem?name=JobInFolder", configXML, MediaType.WILDCARD); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testCreateJobAlreadyExists() throws Exception { - MockWebServer server = mockWebServer(); - - String configXML = payloadFromResource("/freestyle-project.xml"); - server.enqueue(new MockResponse().setHeader("X-Error", "A job already exists with the name ?DevTest?") - .setResponseCode(400)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus success = api.create(null, "DevTest", configXML); - assertNotNull(success); - assertFalse(success.value()); - assertFalse(success.errors().isEmpty()); - assertSentWithXMLFormDataAccept(server, "POST", "/createItem?name=DevTest", configXML, MediaType.WILDCARD); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetDescription() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setBody("whatever").setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - String output = api.description(null,"DevTest"); - assertNotNull(output); - assertEquals(output, "whatever"); - assertSentAcceptText(server, "GET", "/job/DevTest/description"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetDescriptionNonExistentJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - String output = api.description(null,"DevTest"); - assertNull(output); - assertSentAcceptText(server, "GET", "/job/DevTest/description"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testUpdateDescription() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.description(null,"DevTest", "whatever"); - assertTrue(success); - assertSentWithFormData(server, "POST", "/job/DevTest/description", "description=whatever", - MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testUpdateDescriptionNonExistentJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.description(null,"DevTest", "whatever"); - assertFalse(success); - assertSentWithFormData(server, "POST", "/job/DevTest/description", "description=whatever", - MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetConfig() throws Exception { - MockWebServer server = mockWebServer(); - - String configXML = payloadFromResource("/freestyle-project.xml"); - server.enqueue(new MockResponse().setBody(configXML).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - String output = api.config(null,"DevTest"); - assertNotNull(output); - assertEquals(output, configXML); - assertSentAcceptText(server, "GET", "/job/DevTest/config.xml"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetConfigNonExistentJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - String output = api.config(null,"DevTest"); - assertNull(output); - assertSentAcceptText(server, "GET", "/job/DevTest/config.xml"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testUpdateConfig() throws Exception { - MockWebServer server = mockWebServer(); - - String configXML = payloadFromResource("/freestyle-project.xml"); - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.config(null,"DevTest", configXML); - assertTrue(success); - assertSentAccept(server, "POST", "/job/DevTest/config.xml", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testUpdateConfigNonExistentJob() throws Exception { - MockWebServer server = mockWebServer(); - - String configXML = payloadFromResource("/freestyle-project.xml"); - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.config(null,"DevTest", configXML); - assertFalse(success); - assertSentAccept(server, "POST", "/job/DevTest/config.xml", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testDeleteJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus success = api.delete(null,"DevTest"); - assertNotNull(success); - assertTrue(success.value()); - assertTrue(success.errors().isEmpty()); - assertSentAccept(server, "POST", "/job/DevTest/doDelete", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testDeleteJobNonExistent() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(400)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus success = api.delete(null,"DevTest"); - assertNotNull(success); - assertFalse(success.value()); - assertFalse(success.errors().isEmpty()); - assertSentAccept(server, "POST", "/job/DevTest/doDelete", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testEnableJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.enable(null,"DevTest"); - assertTrue(success); - assertSentAccept(server, "POST", "/job/DevTest/enable", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testEnableJobAlreadyEnabled() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.enable(null,"DevTest"); - assertTrue(success); - assertSentAccept(server, "POST", "/job/DevTest/enable", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testDisableJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.disable(null,"DevTest"); - assertTrue(success); - assertSentAccept(server, "POST", "/job/DevTest/disable", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testDisableJobAlreadyEnabled() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.disable(null,"DevTest"); - assertTrue(success); - assertSentAccept(server, "POST", "/job/DevTest/disable", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testBuildJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue( - new MockResponse().setHeader("Location", "http://127.0.1.1:8080/queue/item/1/").setResponseCode(201)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - IntegerResponse output = api.build(null,"DevTest"); - assertNotNull(output); - assertEquals((int) output.value(), 1); - assertEquals(output.errors().size(), 0); - assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testBuildJobWithNoLocationReturned() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue( - new MockResponse().setResponseCode(201)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - IntegerResponse output = api.build(null,"DevTest"); - assertNotNull(output); - assertNull(output.value()); - assertEquals(output.errors().size(), 1); - assertNull(output.errors().get(0).context()); - assertEquals(output.errors().get(0).message(), "No queue item Location header could be found despite getting a valid HTTP response."); - assertEquals(NumberFormatException.class.getCanonicalName(), output.errors().get(0).exceptionName()); - assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testBuildJobNonExistentJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - IntegerResponse output = api.build(null, "DevTest"); - assertNotNull(output); - assertNull(output.value()); - assertEquals(output.errors().size(), 1); - assertEquals(output.errors().get(0).message(), ""); - assertEquals(output.errors().get(0).exceptionName(), "org.jclouds.rest.ResourceNotFoundException"); - assertNotNull(output.errors().get(0).context()); - assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testBuildJobWithParams() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue( - new MockResponse().setHeader("Location", "http://127.0.1.1:8080/queue/item/1/").setResponseCode(201)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - Map> params = new HashMap<>(); - params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); - IntegerResponse output = api.buildWithParameters(null, "DevTest", params); - assertNotNull(output); - assertEquals((int) output.value(), 1); - assertEquals(output.errors().size(), 0); - assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testBuildJobWithNullParamsMap() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue( - new MockResponse().setHeader("Location", "http://127.0.1.1:8080/queue/item/1/").setResponseCode(201)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - IntegerResponse output = api.buildWithParameters(null, "DevTest", null); - assertNotNull(output); - assertEquals((int) output.value(), 1); - assertEquals(output.errors().size(), 0); - assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testBuildJobWithEmptyParamsMap() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue( - new MockResponse().setHeader("Location", "http://127.0.1.1:8080/queue/item/1/").setResponseCode(201)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - IntegerResponse output = api.buildWithParameters(null, "DevTest", new HashMap<>()); - assertNotNull(output); - assertEquals((int) output.value(), 1); - assertEquals(output.errors().size(), 0); - assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testBuildJobWithParamsNonExistentJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - Map> params = new HashMap<>(); - params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); - IntegerResponse output = api.buildWithParameters(null, "DevTest", params); - assertNotNull(output); - assertNull(output.value()); - assertEquals(output.errors().size(), 1); - assertEquals(output.errors().get(0).message(), ""); - assertEquals(output.errors().get(0).exceptionName(), "org.jclouds.rest.ResourceNotFoundException"); - assertNotNull(output.errors().get(0).context()); - assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetParams() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/build-info.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - List output = api.buildInfo(null,"fish", 10).actions().get(0).parameters(); - assertNotNull(output); - assertEquals(output.get(0).name(), "bear"); - assertEquals(output.get(0).value(), "true"); - assertEquals(output.get(1).name(), "fish"); - assertEquals(output.get(1).value(), "salmon"); - assertSent(server, "GET", "/job/fish/10/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetGitCommitInfo() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/build-info-git-commit.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - List changeSets = api.buildInfo(null,"fish", 10).changeSets().get(0).items(); - assertNotNull(changeSets); - assertEquals(changeSets.get(0).affectedPaths().get(0), "some/path/in/the/repository"); - assertEquals(changeSets.get(0).commitId(), "d27afa0805201322d846d7defc29b82c88d9b5ce"); - assertEquals(changeSets.get(0).timestamp(), 1461091892486L); - assertEquals(changeSets.get(0).author().absoluteUrl(), "http://localhost:8080/user/username"); - assertEquals(changeSets.get(0).author().fullName(), "username"); - assertEquals(changeSets.get(0).authorEmail(), "username@localhost"); - assertEquals(changeSets.get(0).comment(), "Commit comment\n"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetParamsWhenNoBuildParams() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/build-info-no-params.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - List output = api.buildInfo(null,"fish", 10).actions().get(0).parameters(); - assertEquals(output.size(), 0); - assertSent(server, "GET", "/job/fish/10/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetParamsWhenEmptyorNullParams() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/build-info-empty-and-null-params.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - List output = api.buildInfo(null,"fish", 10).actions().get(0).parameters(); - assertNotNull(output); - assertEquals(output.get(0).name(), "bear"); - assertEquals(output.get(0).value(), "null"); - assertEquals(output.get(1).name(), "fish"); - assertTrue(output.get(1).value().isEmpty()); - assertSent(server, "GET", "/job/fish/10/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetCause() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/build-info-no-params.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - List output = api.buildInfo(null,"fish", 10).actions().get(0).causes(); - assertNotNull(output); - assertEquals(output.get(0).shortDescription(), "Started by user anonymous"); - assertNull(output.get(0).userId()); - assertEquals(output.get(0).userName(), "anonymous"); - assertSent(server, "GET", "/job/fish/10/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetLastBuildNumber() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/build-number.txt"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - Integer output = api.lastBuildNumber(null,"DevTest"); - assertNotNull(output); - assertEquals((int) output, 123); - assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/buildNumber"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetLastBuildNumberJobNotExist() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - Integer output = api.lastBuildNumber(null,"DevTest"); - assertNull(output); - assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/buildNumber"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetLastBuildTimeStamp() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/build-timestamp.txt"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - String output = api.lastBuildTimestamp(null,"DevTest"); - assertNotNull(output); - assertEquals(body, output); - assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/buildTimestamp"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetLastBuildTimeStampJobNotExist() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - String output = api.lastBuildTimestamp(null,"DevTest"); - assertNull(output); - assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/buildTimestamp"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetProgressiveText() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/progressive-text.txt"); - server.enqueue(new MockResponse().setHeader("X-Text-Size", "123").setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - ProgressiveText output = api.progressiveText(null,"DevTest", 0); - assertNotNull(output); - assertEquals(output.size(), 123); - assertFalse(output.hasMoreData()); - assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/logText/progressiveText?start=0"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetProgressiveTextOfBuildNumber() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/progressive-text.txt"); - server.enqueue(new MockResponse().setHeader("X-Text-Size", "123").setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - ProgressiveText output = api.progressiveText(null,"DevTest", 1,0); - assertNotNull(output); - assertEquals(output.size(), 123); - assertFalse(output.hasMoreData()); - assertSentAcceptText(server, "GET", "/job/DevTest/1/logText/progressiveText?start=0"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetProgressiveTextJobNotExist() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - ProgressiveText output = api.progressiveText(null,"DevTest", 0); - assertNull(output); - assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/logText/progressiveText?start=0"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testRenameJob() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.rename(null,"DevTest","NewDevTest"); - assertTrue(success); - assertSentAccept(server, "POST", "/job/DevTest/doRename?newName=NewDevTest", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testRenameJobNotExist() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - boolean success = api.rename(null,"DevTest","NewDevTest"); - assertFalse(success); - assertSentAccept(server, "POST", "/job/DevTest/doRename?newName=NewDevTest", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testRunHistory() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/runHistory.json"); - - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - List workflows = api.runHistory(null, "MockJob"); - assertNotNull(workflows); - assertSent(server, "GET", "/job/MockJob/wfapi/runs"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testRunHistoryNotExist() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - List workflows = api.runHistory(null, "MockJob"); - assertNull(workflows); - assertSent(server, "GET", "/job/MockJob/wfapi/runs"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testWorkflow() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/workflow.json"); - - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - Workflow success = api.workflow(null,"DevTest",16); - assertNotNull(success); - assertSent(server, "GET", "/job/DevTest/16/wfapi/describe"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testWorkflowNotExist() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - Workflow success = api.workflow(null,"DevTest",16); - assertNull(success); - assertSent(server, "GET", "/job/DevTest/16/wfapi/describe"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testPipelineNode() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/pipeline-node.json"); - - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - PipelineNode success = api.pipelineNode(null,"DevTest",16, 17); - assertNotNull(success); - assertSent(server, "GET", "/job/DevTest/16/execution/node/17/wfapi/describe"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testPipelineNodeNotExist() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - PipelineNode success = api.pipelineNode(null,"DevTest",16, 17); - assertNull(success); - assertSent(server, "GET", "/job/DevTest/16/execution/node/17/wfapi/describe"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testJobTestReportExists() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setHeader("Content-Type", "application/json").setBody("{ \"empty\": false }").setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - JsonObject testReport = api.testReport(null,"DevTest",16); - assertNotNull(testReport); - assertFalse(testReport.get("empty").getAsBoolean()); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testJobTestReportNotExists() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - JsonObject testReport = api.testReport(null,"DevTest",16); - assertNull(testReport); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testPipelineNodeLog() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/pipelineNodeLog.json"); - - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - PipelineNodeLog pipelineNodeLog = api.pipelineNodeLog(null,"MockJob",16, 17); - assertNotNull(pipelineNodeLog); - assertSent(server, "GET", "/job/MockJob/16/execution/node/17/wfapi/log"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testPipelineNodeLogNotExist() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - PipelineNodeLog pipelineNodeLog = api.pipelineNodeLog(null,"MockJob",16, 17); - assertNull(pipelineNodeLog); - assertSent(server, "GET", "/job/MockJob/16/execution/node/17/wfapi/log"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testStopBuild() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus status = api.stop(null, "fish", 99); - assertNotNull(status); - assertTrue(status.value()); - assertTrue(status.errors().isEmpty()); - assertSent(server, "POST", "/job/fish/99/stop"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testTermBuild() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus status = api.term(null, "fish", 99); - assertNotNull(status); - assertTrue(status.value()); - assertTrue(status.errors().isEmpty()); - assertSent(server, "POST", "/job/fish/99/term"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testKillBuild() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus status = api.kill(null, "fish", 99); - assertNotNull(status); - assertTrue(status.value()); - assertTrue(status.errors().isEmpty()); - assertSent(server, "POST", "/job/fish/99/kill"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testTermBuildReturns404() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse() - .setHeader("Location", server.url("/").url() + "job/fish/99/term/") - .setResponseCode(302)); - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus status = api.term(null, "fish", 99); - assertSent(server, "POST", "/job/fish/99/term"); - assertNotNull(status); - assertFalse(status.value()); - assertFalse(status.errors().isEmpty()); - assertEquals(status.errors().size(), 1); - System.out.println("Mock Status: " + status); - assertEquals(status.errors().get(0).message(), "The term operation does not exist for " + - server.url("/").url() + - "job/fish/99/term/, try stop instead."); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testKillBuildReturns404() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse() - .setHeader("Location", server.url("/").url() + "job/fish/99/kill/") - .setResponseCode(302)); - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - JobsApi api = jenkinsApi.jobsApi(); - try { - RequestStatus status = api.kill(null, "fish", 99); - assertSent(server, "POST", "/job/fish/99/kill"); - assertNotNull(status); - assertFalse(status.value()); - assertFalse(status.errors().isEmpty()); - assertEquals(status.errors().size(), 1); - assertEquals(status.errors().get(0).message(), "The kill operation does not exist for " + - server.url("/").url() + - "job/fish/99/kill/, try stop instead."); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/PluginManagerApiLiveTest.java b/src/test/java/com/cdancy/jenkins/rest/features/PluginManagerApiLiveTest.java deleted file mode 100644 index d217bc1..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/PluginManagerApiLiveTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; - -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.plugins.Plugins; - -@Test(groups = "live", testName = "PluginManagerApiLiveTest", singleThreaded = true) -public class PluginManagerApiLiveTest extends BaseJenkinsApiLiveTest { - - @Test - public void testGetPlugins() { - final Plugins plugins = api().plugins(3, null); - assertNotNull(plugins); - assertTrue(plugins.errors().isEmpty()); - assertFalse(plugins.plugins().isEmpty()); - assertNotNull(plugins.plugins().get(0).shortName()); - } - - @Test - public void testInstallNecessaryPlugins() { - final RequestStatus status = api().installNecessaryPlugins("artifactory@2.2.1"); - assertNotNull(status); - assertTrue(status.value()); - assertTrue(status.errors().isEmpty()); - } - - private PluginManagerApi api() { - return api.pluginManagerApi(); - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/PluginManagerApiMockTest.java b/src/test/java/com/cdancy/jenkins/rest/features/PluginManagerApiMockTest.java deleted file mode 100644 index fe9f5da..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/PluginManagerApiMockTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.assertFalse; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.plugins.Plugins; -import com.google.common.collect.Maps; - -import java.util.Map; - -/** - * Mock tests for the {@link com.cdancy.jenkins.rest.features.PluginManagerApi} class. - */ -@Test(groups = "unit", testName = "PluginManagerApiMockTest") -public class PluginManagerApiMockTest extends BaseJenkinsMockTest { - - public void testGetPlugins() throws Exception { - final MockWebServer server = mockWebServer(); - server.enqueue(new MockResponse().setBody(payloadFromResource("/plugins.json")).setResponseCode(200)); - - final JenkinsApi jenkinsApi = api(server.url("/").url()); - final PluginManagerApi api = jenkinsApi.pluginManagerApi(); - try { - final Plugins plugins = api.plugins(3, null); - assertNotNull(plugins); - assertTrue(plugins.errors().isEmpty()); - assertFalse(plugins.plugins().isEmpty()); - assertNotNull(plugins.plugins().get(0).shortName()); - final Map queryParams = Maps.newHashMap(); - queryParams.put("depth", 3); - assertSent(server, "GET", "/pluginManager/api/json", queryParams); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetPluginsOnAuthException() throws Exception { - final MockWebServer server = mockWebServer(); - server.enqueue(new MockResponse().setResponseCode(401)); - - final JenkinsApi jenkinsApi = api(server.url("/").url()); - final PluginManagerApi api = jenkinsApi.pluginManagerApi(); - try { - final Plugins plugins = api.plugins(3, null); - assertNotNull(plugins); - assertNull(plugins.clazz()); - assertFalse(plugins.errors().isEmpty()); - assertTrue(plugins.errors().get(0).exceptionName().endsWith("AuthorizationException")); - final Map queryParams = Maps.newHashMap(); - queryParams.put("depth", 3); - assertSent(server, "GET", "/pluginManager/api/json", queryParams); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testInstallNecessaryPlugins() throws Exception { - final MockWebServer server = mockWebServer(); - server.enqueue(new MockResponse().setResponseCode(200)); - - final JenkinsApi jenkinsApi = api(server.url("/").url()); - final PluginManagerApi api = jenkinsApi.pluginManagerApi(); - try { - final RequestStatus status = api.installNecessaryPlugins("artifactory@2.2.1"); - assertNotNull(status); - assertTrue(status.value()); - assertTrue(status.errors().isEmpty()); - assertSent(server, "POST", "/pluginManager/installNecessaryPlugins"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testInstallNecessaryPluginsOnAuthException() throws Exception { - final MockWebServer server = mockWebServer(); - server.enqueue(new MockResponse().setResponseCode(401)); - - final JenkinsApi jenkinsApi = api(server.url("/").url()); - final PluginManagerApi api = jenkinsApi.pluginManagerApi(); - try { - final RequestStatus status = api.installNecessaryPlugins("artifactory@2.2.1"); - assertNotNull(status); - assertFalse(status.value()); - assertFalse(status.errors().isEmpty()); - assertTrue(status.errors().get(0).exceptionName().endsWith("AuthorizationException")); - assertSent(server, "POST", "/pluginManager/installNecessaryPlugins"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/QueueApiLiveTest.java b/src/test/java/com/cdancy/jenkins/rest/features/QueueApiLiveTest.java deleted file mode 100644 index 0d6ce49..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/QueueApiLiveTest.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest; -import com.cdancy.jenkins.rest.domain.common.IntegerResponse; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.queue.QueueItem; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -@Test(groups = "live", testName = "QueueApiLiveTest", singleThreaded = true) -public class QueueApiLiveTest extends BaseJenkinsApiLiveTest { - - @BeforeClass - public void init() { - String config = payloadFromResource("/freestyle-project-sleep-task.xml"); - RequestStatus success = api.jobsApi().create(null,"QueueTest", config); - assertTrue(success.value()); - - config = payloadFromResource("/freestyle-project.xml"); - success = api.jobsApi().create(null,"QueueTestSingleParam", config); - assertTrue(success.value()); - - config = payloadFromResource("/freestyle-project-sleep-task-multiple-params.xml"); - success = api.jobsApi().create(null,"QueueTestMultipleParams", config); - assertTrue(success.value()); - } - - @Test - public void testGetQueue() { - IntegerResponse job1 = api.jobsApi().build(null, "QueueTest"); - assertNotNull(job1); - assertEquals(job1.errors().size(), 0); - IntegerResponse job2 = api.jobsApi().build(null, "QueueTest"); - assertNotNull(job2); - assertEquals(job2.errors().size(), 0); - List queueItems = api().queue(); - assertTrue(queueItems.size() > 0); - boolean foundLastKickedJob = false; - for (QueueItem item : queueItems) { - if (item.id() == job2.value()) { - foundLastKickedJob = true; - break; - } - } - assertTrue(foundLastKickedJob); - } - - @Test - public void testGetPendingQueueItem() { - IntegerResponse job1 = api.jobsApi().build(null,"QueueTest"); - assertNotNull(job1); - assertEquals(job1.errors().size(), 0); - IntegerResponse job2 = api.jobsApi().build(null,"QueueTest"); - assertNotNull(job2); - assertEquals(job2.errors().size(), 0); - - // job2 is queue after job1, so while job1 runs, job2 is pending in the queue - QueueItem queueItem = api().queueItem(job2.value()); - assertFalse(queueItem.cancelled()); - assertNotNull(queueItem.why()); - assertNull(queueItem.executable()); - } - - @Test - public void testGetRunningQueueItem() throws InterruptedException { - IntegerResponse job1 = api.jobsApi().build(null,"QueueTest"); - assertNotNull(job1); - assertEquals(job1.errors().size(), 0); - IntegerResponse job2 = api.jobsApi().build(null,"QueueTest"); - assertNotNull(job2); - assertEquals(job2.errors().size(), 0); - - // job1 runs first, so we get its queueItem - QueueItem queueItem = getRunningQueueItem(job1.value()); - - // If null, it means the queueItem has been cancelled, which would not be normal in this test - assertNotNull(queueItem); - assertFalse(queueItem.cancelled()); - - // We exepect this build to run, consequently: - // * the why field should now be null - // * the executable field should NOT be null - // * the build number should be set to an integer - // * the url for the build should be set to a string - assertNull(queueItem.why()); - assertNotNull(queueItem.executable()); - } - - @Test - public void testQueueItemSingleParameters() throws InterruptedException { - Map> params = new HashMap<>(); - params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue1")); - IntegerResponse job1 = api.jobsApi().buildWithParameters(null,"QueueTestSingleParam", params); - assertNotNull(job1); - assertTrue(job1.value() > 0); - assertEquals(job1.errors().size(), 0); - - // Jenkins will reject two consecutive build requests when the build parameter values are the same - // So we must set some different parameter values - params = new HashMap<>(); - params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue2")); - IntegerResponse job2 = api.jobsApi().buildWithParameters(null,"QueueTestSingleParam", params); - assertNotNull(job2); - assertTrue(job2.value() > 0); - assertEquals(job2.errors().size(), 0); - - QueueItem queueItem = getRunningQueueItem(job1.value()); - assertNotNull(queueItem); - assertFalse(queueItem.cancelled()); - - Map map = Maps.newHashMap(); - map.put("SomeKey", "SomeVeryNewValue1"); - assertEquals(queueItem.params(), map); - } - - @Test - public void testQueueItemMultipleParameters() throws InterruptedException { - Map> params = new HashMap<>(); - params.put("SomeKey1", Lists.newArrayList("SomeVeryNewValue1")); - IntegerResponse job1 = api.jobsApi().buildWithParameters(null, "QueueTestMultipleParams",params); - assertNotNull(job1); - assertTrue(job1.value() > 0); - assertEquals(job1.errors().size(), 0); - - // Jenkins will reject two consecutive build requests when the build parameter values are the same - // So we must set some different parameter values - params = new HashMap<>(); - params.put("SomeKey1", Lists.newArrayList("SomeVeryNewValue2")); - IntegerResponse job2 = api.jobsApi().buildWithParameters(null, "QueueTestMultipleParams", params); - assertNotNull(job2); - assertTrue(job2.value() > 0); - assertEquals(job2.errors().size(), 0); - - QueueItem queueItem = getRunningQueueItem(job1.value()); - assertNotNull(queueItem); - assertFalse(queueItem.cancelled()); - - Map map = Maps.newHashMap(); - map.put("SomeKey1", "SomeVeryNewValue1"); - map.put("SomeKey2", "SomeValue2"); - map.put("SomeKey3", "SomeValue3"); - assertEquals(queueItem.params(), map); - } - - @Test - public void testQueueItemEmptyParameterValue() throws InterruptedException { - Map> params = new HashMap<>(); - params.put("SomeKey1", Lists.newArrayList("")); - IntegerResponse job1 = api.jobsApi().buildWithParameters(null, "QueueTestMultipleParams",params); - assertNotNull(job1); - assertTrue(job1.value() > 0); - assertEquals(job1.errors().size(), 0); - - QueueItem queueItem = getRunningQueueItem(job1.value()); - assertNotNull(queueItem); - - Map map = Maps.newHashMap(); - map.put("SomeKey1", ""); - map.put("SomeKey2", "SomeValue2"); - map.put("SomeKey3", "SomeValue3"); - assertEquals(queueItem.params(), map); - } - - @Test - public void testGetCancelledQueueItem() { - IntegerResponse job1 = api.jobsApi().build(null,"QueueTest"); - assertNotNull(job1); - assertEquals(job1.errors().size(), 0); - IntegerResponse job2 = api.jobsApi().build(null, "QueueTest"); - assertNotNull(job2); - assertEquals(job2.errors().size(), 0); - - RequestStatus success = api().cancel(job2.value()); - assertNotNull(success); - assertTrue(success.value()); - assertTrue(success.errors().isEmpty()); - - QueueItem queueItem = api().queueItem(job2.value()); - assertTrue(queueItem.cancelled()); - assertNull(queueItem.why()); - assertNull(queueItem.executable()); - } - - @Test - public void testCancelNonExistentQueueItem() { - RequestStatus success = api().cancel(123456789); - assertNotNull(success); - assertTrue(success.value()); - assertTrue(success.errors().isEmpty()); - } - - @AfterClass - public void finish() { - RequestStatus success = api.jobsApi().delete(null,"QueueTest"); - assertNotNull(success); - assertTrue(success.value()); - - success = api.jobsApi().delete(null,"QueueTestSingleParam"); - assertNotNull(success); - assertTrue(success.value()); - - success = api.jobsApi().delete(null,"QueueTestMultipleParams"); - assertNotNull(success); - assertTrue(success.value()); - } - - private QueueApi api() { - return api.queueApi(); - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/QueueApiMockTest.java b/src/test/java/com/cdancy/jenkins/rest/features/QueueApiMockTest.java deleted file mode 100644 index 6a3408f..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/QueueApiMockTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; - -import java.util.List; -import java.util.Map; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.domain.queue.QueueItem; -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; - -import com.google.common.collect.Maps; - -/** - * Mock tests for the {@link com.cdancy.jenkins.rest.features.QueueApi} class. - */ -@Test(groups = "unit", testName = "QueueApiMockTest") -public class QueueApiMockTest extends BaseJenkinsMockTest { - - public void testGetQueue() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/queue.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - QueueApi api = jenkinsApi.queueApi(); - try { - List output = api.queue(); - assertEquals(output.size(), 2); - assertSent(server, "GET", "/queue/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetPendingQueueItem() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/queueItemPending.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); - try { - assertFalse(queueItem.cancelled()); - assertEquals(queueItem.why(), "Build #9 is already in progress (ETA:15 sec)"); - assertNull(queueItem.executable()); - assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetCancelledQueueItem() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/queueItemCancelled.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); - try { - assertTrue(queueItem.cancelled()); - assertNull(queueItem.why()); - assertNull(queueItem.executable()); - assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetRunningQueueItem() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/queueItemRunning.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - int buildNumber = 14; - QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); - Map map = Maps.newHashMap(); - map.put("a", "4"); - try { - assertEquals(queueItem.params(), map); - assertFalse(queueItem.cancelled()); - assertNull(queueItem.why()); - assertNotNull(queueItem.executable()); - assertEquals((int) queueItem.executable().number(), buildNumber); - assertEquals(queueItem.executable().url(), "http://localhost:8082/job/test/" + buildNumber + "/"); - assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testQueueItemMultipleParameters() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/queueItemMultipleParameters.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); - Map map = Maps.newHashMap(); - map.put("a", "1"); - map.put("b", "2"); - map.put("c", "3"); - try { - assertEquals(queueItem.params(), map); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testQueueItemEmptyParameterValue() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/queueItemEmptyParameterValue.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); - Map map = Maps.newHashMap(); - map.put("a", "1"); - map.put("b", ""); - map.put("c", "3"); - try { - assertEquals(queueItem.params(), map); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testCancelQueueItem() throws Exception { - MockWebServer server = mockWebServer(); - server.enqueue(new MockResponse().setResponseCode(404)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - RequestStatus result = jenkinsApi.queueApi().cancel(queueItemId); - try { - assertNotNull(result); - assertTrue(result.value()); - assertTrue(result.errors().isEmpty()); - assertSentWithFormData(server, "POST", "/queue/cancelItem", "id=" + queueItemId); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testCancelNonExistentQueueItem() throws Exception { - MockWebServer server = mockWebServer(); - server.enqueue(new MockResponse().setResponseCode(500)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - RequestStatus result = jenkinsApi.queueApi().cancel(queueItemId); - try { - assertNotNull(result); - assertFalse(result.value()); - assertFalse(result.errors().isEmpty()); - assertSentWithFormData(server, "POST", "/queue/cancelItem", "id=" + queueItemId); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testQueueItemNullTaskName() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/queueItemNullTaskName.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); - try { - assertFalse(queueItem.cancelled()); - assertEquals(queueItem.why(), "Build #9 is already in progress (ETA:15 sec)"); - assertNull(queueItem.executable()); - assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testQueueItemMissingTaskUrl() throws Exception { - MockWebServer server = mockWebServer(); - String body = payloadFromResource("/queueItemMissingTaskUrl.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - int queueItemId = 143; - QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); - try { - assertFalse(queueItem.cancelled()); - assertEquals(queueItem.why(), "Just a random message here"); - assertNull(queueItem.executable()); - assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/StatisticsApiLiveTest.java b/src/test/java/com/cdancy/jenkins/rest/features/StatisticsApiLiveTest.java deleted file mode 100644 index b37e7ec..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/StatisticsApiLiveTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import static org.testng.Assert.assertNotNull; - -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest; -import com.cdancy.jenkins.rest.domain.statistics.OverallLoad; - -@Test(groups = "live", testName = "StatisticsApiLiveTest", singleThreaded = true) -public class StatisticsApiLiveTest extends BaseJenkinsApiLiveTest { - @Test - public void testOverallLoad() { - OverallLoad load = api().overallLoad(); - assertNotNull(load); - } - private StatisticsApi api() { - return api.statisticsApi(); - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/StatisticsApiMockTest.java b/src/test/java/com/cdancy/jenkins/rest/features/StatisticsApiMockTest.java deleted file mode 100644 index 63d4731..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/StatisticsApiMockTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import static org.testng.Assert.assertNotNull; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.domain.statistics.OverallLoad; -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; - -/** - * Mock tests for the {@link com.cdancy.jenkins.rest.features.StatisticsApi} - * class. - */ -@Test(groups = "unit", testName = "StatisticsApiMockTest") -public class StatisticsApiMockTest extends BaseJenkinsMockTest { - - public void testOverallLoad() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setBody(payloadFromResource("/overall-load.json")).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - StatisticsApi api = jenkinsApi.statisticsApi(); - try { - OverallLoad load = api.overallLoad(); - assertNotNull(load); - assertSent(server, "GET", "/overallLoad/api/json"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/SystemApiMockTest.java b/src/test/java/com/cdancy/jenkins/rest/features/SystemApiMockTest.java deleted file mode 100644 index a9bb903..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/SystemApiMockTest.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.assertFalse; - -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.JenkinsApiMetadata; -import com.cdancy.jenkins.rest.domain.system.SystemInfo; -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; - -import javax.ws.rs.core.MediaType; - -/** - * Mock tests for the {@link com.cdancy.jenkins.rest.features.SystemApi} class. - */ -@Test(groups = "unit", testName = "SystemApiMockTest") -public class SystemApiMockTest extends BaseJenkinsMockTest { - - public void testGetSystemInfo() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue( - new MockResponse().setHeader("X-Hudson", "1.395").setHeader("X-Jenkins", JenkinsApiMetadata.BUILD_VERSION) - .setHeader("X-Jenkins-Session", "cc323b8d").setHeader("X-Hudson-CLI-Port", "50000") - .setHeader("X-Jenkins-CLI-Port", "50000").setHeader("X-Jenkins-CLI2-Port", "50000") - .setHeader("X-Instance-Identity", "fdsa").setHeader("X-SSH-Endpoint", "127.0.1.1:46126") - .setHeader("Server", "Jetty(winstone-2.9)").setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - SystemApi api = jenkinsApi.systemApi(); - try { - final SystemInfo version = api.systemInfo(); - assertNotNull(version); - assertTrue(version.jenkinsVersion().equalsIgnoreCase(JenkinsApiMetadata.BUILD_VERSION)); - assertSent(server, "HEAD", "/"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testGetSystemInfoOnError() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue( - new MockResponse().setBody("Not Authorized").setResponseCode(401)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - SystemApi api = jenkinsApi.systemApi(); - try { - final SystemInfo version = api.systemInfo(); - assertNotNull(version); - assertFalse(version.errors().isEmpty()); - assertSent(server, "HEAD", "/"); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testQuietDown() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - SystemApi api = jenkinsApi.systemApi(); - try { - RequestStatus success = api.quietDown(); - assertNotNull(success); - assertTrue(success.value()); - assertSentAccept(server, "POST", "/quietDown", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testQuietDownOnAuthException() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(401)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - SystemApi api = jenkinsApi.systemApi(); - try { - RequestStatus status = api.quietDown(); - assertFalse(status.value()); - assertFalse(status.errors().isEmpty()); - assertTrue(status.errors().get(0).exceptionName().endsWith("AuthorizationException")); - assertSentAccept(server, "POST", "/quietDown", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testCancelQuietDown() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - SystemApi api = jenkinsApi.systemApi(); - try { - RequestStatus success = api.cancelQuietDown(); - assertNotNull(success); - assertTrue(success.value()); - assertSentAccept(server, "POST", "/cancelQuietDown", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - public void testCancelQuietDownOnAuthException() throws Exception { - MockWebServer server = mockWebServer(); - - server.enqueue(new MockResponse().setResponseCode(401)); - JenkinsApi jenkinsApi = api(server.url("/").url()); - SystemApi api = jenkinsApi.systemApi(); - try { - RequestStatus status = api.cancelQuietDown(); - assertFalse(status.value()); - assertFalse(status.errors().isEmpty()); - assertTrue(status.errors().get(0).exceptionName().endsWith("AuthorizationException")); - assertSentAccept(server, "POST", "/cancelQuietDown", MediaType.TEXT_HTML); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/UserApiLiveTest.java b/src/test/java/com/cdancy/jenkins/rest/features/UserApiLiveTest.java deleted file mode 100644 index 1d0c239..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/UserApiLiveTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.user.*; -import org.testng.annotations.Test; - -import static org.testng.Assert.*; - -@Test(groups = "live", testName = "UserApiLiveTest", singleThreaded = true) -public class UserApiLiveTest extends BaseJenkinsApiLiveTest { - - ApiToken token; - - @Test - public void testGetUser() { - User user = api().get(); - assertNotNull(user); - assertNotNull(user.absoluteUrl()); - assertEquals(user.absoluteUrl(), System.getProperty("test.jenkins.endpoint") + "/user/admin"); - assertTrue(user.description() == null || user.description().equals("")); - assertNotNull(user.fullName()); - assertEquals(user.fullName(), "admin"); - assertNotNull(user.id()); - assertEquals(user.id(), "admin"); - } - - @Test - public void testGenerateNewToken() { - token = api().generateNewToken("user-api-test-token"); - assertNotNull(token); - assertEquals(token.status(), "ok"); - assertNotNull(token.data()); - assertNotNull(token.data().tokenName()); - assertEquals(token.data().tokenName(), "user-api-test-token"); - assertNotNull(token.data().tokenUuid()); - assertNotNull(token.data().tokenValue()); - } - - @Test(dependsOnMethods = "testGenerateNewToken") - public void testRevokeApiToken() { - RequestStatus status = api().revoke(token.data().tokenUuid()); - // Jenkins returns 200 whether the tokenUuid is correct or not. - assertTrue(status.value()); - } - - @Test - public void testRevokeApiTokenWithEmptyUuid() { - RequestStatus status = api().revoke(""); - assertFalse(status.value()); - // TODO: Deal with the HTML response from Jenkins Stapler - } - - private UserApi api() { - return api.userApi(); - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/UserApiMockTest.java b/src/test/java/com/cdancy/jenkins/rest/features/UserApiMockTest.java deleted file mode 100644 index a9b6700..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/features/UserApiMockTest.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - */ -package com.cdancy.jenkins.rest.features; - -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.domain.user.ApiToken; -import com.cdancy.jenkins.rest.domain.user.User; -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.testng.annotations.Test; - -import static org.testng.Assert.*; - -/** - * Mock tests for the {@link com.cdancy.jenkins.rest.features.JobsApi} class. - */ -@Test(groups = "unit", testName = "UserApiMockTest") -public class UserApiMockTest extends BaseJenkinsMockTest { - - @Test - public void testGetUser() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/user.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - //JenkinsApi jenkinsApi = api(server.url("/").url()); - try (JenkinsApi jenkinsApi = api(server.url("/").url())) { - UserApi api = jenkinsApi.userApi(); - User output = api.get(); - assertNotNull(output); - assertNotNull(output.absoluteUrl()); - assertEquals(output.absoluteUrl(), "http://localhost:8080/user/admin"); - assertNull(output.description()); - assertNotNull(output.fullName()); - assertEquals(output.fullName(), "Administrator"); - assertNotNull(output.id()); - assertEquals(output.id(), "admin"); - assertSent(server, "GET", "/user/user/api/json"); - } finally { - server.shutdown(); - } - } - - @Test - public void testGenerateNewApiToken() throws Exception { - MockWebServer server = mockWebServer(); - - String body = payloadFromResource("/api-token.json"); - server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); - try (JenkinsApi jenkinsApi = api(server.url("/").url())) { - UserApi api = jenkinsApi.userApi(); - ApiToken output = api.generateNewToken("random"); - assertNotNull(output); - assertNotNull(output.status()); - assertEquals(output.status(), "ok"); - assertNotNull(output.data()); - assertNotNull(output.data().tokenName()); - assertEquals(output.data().tokenName(), "kb-token"); - assertNotNull(output.data().tokenUuid()); - assertEquals(output.data().tokenUuid(), "8c42630b-4be5-4f51-b4e9-f17a8ac07521"); - assertNotNull(output.data().tokenValue()); - assertEquals(output.data().tokenValue(), "112fe6e9b1b94eb1ee58f0ea4f5a1ac7bf"); - assertSentWithFormData(server, "POST", "/user/user/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken", "newTokenName=random"); - } finally { - server.shutdown(); - } - } - - // TODO: testRevokeApiToken - // TODO: testRevokeApiTokenWithEmptyUuid -} diff --git a/src/test/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilterMockTest.java b/src/test/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilterMockTest.java deleted file mode 100644 index 6e6aae8..0000000 --- a/src/test/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilterMockTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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. - */ - -package com.cdancy.jenkins.rest.filters; - -import javax.ws.rs.core.MediaType; - -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.JenkinsAuthentication; -import com.cdancy.jenkins.rest.auth.AuthenticationType; -import com.cdancy.jenkins.rest.BaseJenkinsMockTest; - -import okhttp3.mockwebserver.MockResponse; -import okhttp3.mockwebserver.MockWebServer; -import org.jclouds.http.HttpRequest; - -import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; - -import com.google.common.collect.Multimap; - -public class JenkinsAuthenticationFilterMockTest extends BaseJenkinsMockTest { - - @Test - public void testAnonymousNeedsCrumb() throws Exception { - MockWebServer server = mockWebServer(); - - final String value = "04a1109fc2db171362c966ebe9fc87f0"; - server.enqueue(new MockResponse().setBody("Jenkins-Crumb:" + value).setResponseCode(200)); - JenkinsApi jenkinsApi = anonymousAuthApi(server.url("/").url()); - - JenkinsAuthentication creds = creds(AuthenticationType.Anonymous, null); - JenkinsAuthenticationFilter filter = new JenkinsAuthenticationFilter(creds, jenkinsApi); - HttpRequest httpRequest = HttpRequest.builder().endpoint(server.url("/").url().toString()).method("POST").build(); - try { - httpRequest = filter.filter(httpRequest); - assertEquals(httpRequest.getEndpoint().toString(), server.url("/").url().toString()); - assertSentAccept(server, "GET", "/crumbIssuer/api/xml?xpath=concat%28//crumbRequestField,%22%3A%22,//crumb%29", MediaType.TEXT_PLAIN); - Multimap headers = httpRequest.getHeaders(); - assertEquals(headers.size(), 2); - assertTrue(headers.containsEntry("Jenkins-Crumb",value)); - assertTrue(headers.containsEntry("Cookie","")); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - @Test - public void testUsernamePasswordNeedsCrumb() throws Exception { - MockWebServer server = mockWebServer(); - - final String value = "04a1109fc2db171362c966ebe9fc87f0"; - final String usernamePassword = "random_user:random_password"; - server.enqueue(new MockResponse().setBody("Jenkins-Crumb:" + value).setResponseCode(200)); - JenkinsApi jenkinsApi = api(server.url("/").url(), AuthenticationType.UsernamePassword, usernamePassword); - - JenkinsAuthentication creds = creds(AuthenticationType.UsernamePassword, usernamePassword); - JenkinsAuthenticationFilter filter = new JenkinsAuthenticationFilter(creds, jenkinsApi); - HttpRequest httpRequest = HttpRequest.builder().endpoint(server.url("/").url().toString()).method("POST").build(); - try { - httpRequest = filter.filter(httpRequest); - assertEquals(httpRequest.getEndpoint().toString(), server.url("/").url().toString()); - assertSentAccept(server, "GET", "/crumbIssuer/api/xml?xpath=concat%28//crumbRequestField,%22%3A%22,//crumb%29", MediaType.TEXT_PLAIN); - Multimap headers = httpRequest.getHeaders(); - assertEquals(headers.size(), 3); - assertTrue(headers.containsEntry("Jenkins-Crumb",value)); - assertTrue(headers.containsEntry("Authorization", creds.authType().getAuthScheme() + " " + creds.authValue())); - assertTrue(headers.containsEntry("Cookie","")); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - @Test - public void testUsernameApiTokenNeedsNoCrumb() throws Exception { - MockWebServer server = mockWebServer(); - - JenkinsApi jenkinsApi = api(server.url("/").url()); - - JenkinsAuthentication creds = creds(AuthenticationType.UsernameApiToken, "random_user:random_token"); - JenkinsAuthenticationFilter filter = new JenkinsAuthenticationFilter(creds, jenkinsApi); - HttpRequest httpRequest = HttpRequest.builder().endpoint(server.url("/").url().toString()).method("POST").build(); - try { - httpRequest = filter.filter(httpRequest); - assertEquals(httpRequest.getEndpoint().toString(), server.url("/").url().toString()); - Multimap headers = httpRequest.getHeaders(); - assertEquals(headers.size(), 1); - assertTrue(headers.containsEntry("Authorization", creds.authType().getAuthScheme() + " " + creds.authValue())); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } - - @Test - public void getMethodNeedsNoCrumb() throws Exception { - MockWebServer server = mockWebServer(); - - JenkinsApi jenkinsApi = api(server.url("/").url()); - - JenkinsAuthentication creds = creds(AuthenticationType.UsernameApiToken, "random_user:random_token"); - JenkinsAuthenticationFilter filter = new JenkinsAuthenticationFilter(creds, jenkinsApi); - HttpRequest httpRequest = HttpRequest.builder().endpoint(server.url("/").url().toString()).method("GET").build(); - try { - httpRequest = filter.filter(httpRequest); - assertEquals(httpRequest.getEndpoint().toString(), server.url("/").url().toString()); - Multimap headers = httpRequest.getHeaders(); - assertEquals(headers.size(), 1); - assertTrue(headers.containsEntry("Authorization", creds.authType().getAuthScheme() + " " + creds.authValue())); - } finally { - jenkinsApi.close(); - server.shutdown(); - } - } -} diff --git a/src/test/java/com/cdancy/jenkins/rest/BaseJenkinsApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsApiLiveTest.java similarity index 53% rename from src/test/java/com/cdancy/jenkins/rest/BaseJenkinsApiLiveTest.java rename to src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsApiLiveTest.java index 588a9f9..8d814cb 100644 --- a/src/test/java/com/cdancy/jenkins/rest/BaseJenkinsApiLiveTest.java +++ b/src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsApiLiveTest.java @@ -14,78 +14,65 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.cdancy.jenkins.rest; +package io.github.hmedioni.jenkins.client; -import com.cdancy.jenkins.rest.config.JenkinsAuthenticationModule; -import static org.jclouds.util.Strings2.toStringAndClose; +import com.fasterxml.jackson.databind.*; +import io.github.hmedioni.jenkins.client.config.*; +import io.github.hmedioni.jenkins.client.domain.job.*; +import io.github.hmedioni.jenkins.client.domain.queue.*; +import org.testng.annotations.*; -import java.io.IOException; -import java.util.Objects; -import java.util.Properties; -import java.util.UUID; +import java.io.*; +import java.nio.charset.*; +import java.util.*; -import com.cdancy.jenkins.rest.domain.job.BuildInfo; -import com.cdancy.jenkins.rest.domain.queue.QueueItem; -import org.jclouds.Constants; -import org.jclouds.apis.BaseApiLiveTest; -import org.testng.annotations.Test; - -import com.google.common.base.Charsets; -import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableSet; -import com.google.inject.Module; @Test(groups = "live") -public class BaseJenkinsApiLiveTest extends BaseApiLiveTest { +public class BaseJenkinsApiLiveTest { protected final JenkinsAuthentication jenkinsAuthentication; + final protected ObjectMapper objectMapper = new ObjectMapper(); + + final protected String url = "http://127.0.0.1:8080"; + final private String user = "admin"; + final private String password = "admin"; + protected JenkinsProperties jenkinsProperties = new JenkinsProperties(url, user, password); + protected JenkinsClient jenkinsClient = JenkinsClient.create(jenkinsProperties); + protected JenkinsApi api = jenkinsClient.api(); + public BaseJenkinsApiLiveTest() { - provider = "jenkins"; this.jenkinsAuthentication = TestUtilities.inferTestAuthentication(); } - @Override - protected Properties setupProperties() { - Properties overrides = super.setupProperties(); - overrides.setProperty(Constants.PROPERTY_MAX_RETRIES, "0"); - return overrides; - } - protected String randomString() { return UUID.randomUUID().toString().replaceAll("-", ""); } - public String payloadFromResource(String resource) { + public String payloadFromResource(final String resource) { try { - return new String(toStringAndClose(Objects.requireNonNull(getClass().getResourceAsStream(resource))).getBytes(Charsets.UTF_8)); + return new String((getClass().getResourceAsStream(resource)).readAllBytes(), StandardCharsets.UTF_8); } catch (IOException e) { - throw Throwables.propagate(e); + throw new RuntimeException(e); } } - @Override - protected Iterable setupModules() { - final JenkinsAuthenticationModule credsModule = new JenkinsAuthenticationModule(this.jenkinsAuthentication); - return ImmutableSet.of(getLoggingModule(), credsModule); - } - /** * Return a queue item that is being built. * If the queue item is canceled before the build is launched, null is returned. * To prevent the test from hanging, this method times out after 10 attempts and the queue item is returned the way it is. - * @param queueId The queue id returned when asking Jenkins to run a build. - * @return Null if the queue item has been canceled before it has had a chance to run, - * otherwise the QueueItem element is returned, but this does not guarantee that the build runs. - * The caller has to check the value of queueItem.executable, and if it is null, the queue item is still pending. * + * @param queueId The queue id returned when asking Jenkins to run a build. + * @return Null if the queue item has been canceled before it has had a chance to run, + * otherwise the QueueItem element is returned, but this does not guarantee that the build runs. + * The caller has to check the value of queueItem.executable, and if it is null, the queue item is still pending. */ protected QueueItem getRunningQueueItem(int queueId) throws InterruptedException { int max = 10; QueueItem queueItem = api.queueApi().queueItem(queueId); while (max > 0) { - if (queueItem.cancelled()) return null; - if (queueItem.executable() != null) { + if (queueItem.isCancelled()) return null; + if (queueItem.getExecutable() != null) { return queueItem; } Thread.sleep(2000); @@ -97,10 +84,10 @@ protected QueueItem getRunningQueueItem(int queueId) throws InterruptedException protected BuildInfo getCompletedBuild(String jobName, QueueItem queueItem) throws InterruptedException { int max = 10; - BuildInfo buildInfo = api.jobsApi().buildInfo(null, jobName, queueItem.executable().number()); - while (buildInfo.result() == null) { + BuildInfo buildInfo = api.jobsApi().buildInfo(null, jobName, queueItem.getExecutable().getNumber()); + while (buildInfo.getResult() == null) { Thread.sleep(2000); - buildInfo = api.jobsApi().buildInfo(null, jobName, queueItem.executable().number()); + buildInfo = api.jobsApi().buildInfo(null, jobName, queueItem.getExecutable().getNumber()); } return buildInfo; } diff --git a/src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsMockTest.java new file mode 100644 index 0000000..fdad1f7 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsMockTest.java @@ -0,0 +1,145 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client; +// +//import okhttp3.mockwebserver.*; +//import org.springframework.http.*; +// +//import java.io.*; +//import java.util.*; +// +//import static org.assertj.core.api.Assertions.*; +// +///** +// * Base class for all Jenkins mock tests. +// */ +//public class BaseJenkinsMockTest extends BaseJenkinsTest { +// +// /** +// * Create a MockWebServer with an initial bread-crumb response. +// * +// * @return instance of MockWebServer +// * @throws IOException if unable to start/play server +// */ +// public static MockWebServer mockWebServer() throws IOException { +// final MockWebServer server = new MockWebServer(); +// server.start(); +// return server; +// } +// +// private static Map extractParams(final String path) { +// +// final int qmIndex = path.indexOf('?'); +// if (qmIndex <= 0) { +// return ImmutableMap.of(); +// } +// +// final ImmutableMap.Builder builder = ImmutableMap.builder(); +// +// final String[] params = path.substring(qmIndex + 1).split("&"); +// for (final String param : params) { +// final String[] keyValue = param.split("=", 2); +// if (keyValue.length > 1) { +// builder.put(keyValue[0], keyValue[1]); +// } +// } +// +// return builder.build(); +// } +// +// protected RecordedRequest assertSent(final MockWebServer server, +// final String method, +// final String path) throws InterruptedException { +// +// return assertSent(server, method, path, ImmutableMap.of()); +// } +// +// protected RecordedRequest assertSent(final MockWebServer server, +// final String method, +// final String expectedPath, +// final Map queryParams) throws InterruptedException { +// +// RecordedRequest request = server.takeRequest(); +// assertThat(request.getMethod()).isEqualTo(method); +// assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON); +// +// final String path = request.getPath(); +// final String rawPath = path.contains("?") ? path.substring(0, path.indexOf('?')) : path; +// assertThat(rawPath).isEqualTo(expectedPath); +// +// final Map normalizedParams = Maps.transformValues(queryParams, Functions.toStringFunction()); +// assertThat(normalizedParams).isEqualTo(extractParams(path)); +// +// return request; +// } +// +// protected RecordedRequest assertSentWithFormData(final MockWebServer server, +// final String method, +// final String path, +// final String body) throws InterruptedException { +// +// RecordedRequest request = server.takeRequest(); +// assertThat(request.getMethod()).isEqualTo(method); +// assertThat(request.getPath()).isEqualTo(path); +// assertThat(request.getUtf8Body()).isEqualTo(body); +// assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.APPLICATION_JSON); +// assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo(MediaType.APPLICATION_FORM_URLENCODED); +// return request; +// } +// +// protected RecordedRequest assertSentWithFormData(MockWebServer server, String method, +// String path, String body, +// String acceptType) throws InterruptedException { +// +// RecordedRequest request = server.takeRequest(); +// assertThat(request.getMethod()).isEqualTo(method); +// assertThat(request.getPath()).isEqualTo(path); +// assertThat(request.getUtf8Body()).isEqualTo(body); +// assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(acceptType); +// assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo(MediaType.APPLICATION_FORM_URLENCODED); +// return request; +// } +// +// protected RecordedRequest assertSentWithXMLFormDataAccept(MockWebServer server, String method, String path, +// String body, String acceptType) throws InterruptedException { +// +// RecordedRequest request = server.takeRequest(); +// assertThat(request.getMethod()).isEqualTo(method); +// assertThat(request.getPath()).isEqualTo(path); +// assertThat(request.getUtf8Body()).isEqualTo(body); +// assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(acceptType); +// assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo(MediaType.APPLICATION_XML); +// return request; +// } +// +// protected RecordedRequest assertSentAcceptText(MockWebServer server, String method, String path) throws InterruptedException { +// RecordedRequest request = server.takeRequest(); +// assertThat(request.getMethod()).isEqualTo(method); +// assertThat(request.getPath()).isEqualTo(path); +// assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(MediaType.TEXT_PLAIN); +// return request; +// } +// +// protected RecordedRequest assertSentAccept(MockWebServer server, String method, String path, String acceptType) throws InterruptedException { +// RecordedRequest request = server.takeRequest(); +// assertThat(request.getMethod()).isEqualTo(method); +// assertThat(request.getPath()).isEqualTo(path); +// assertThat(request.getHeader(HttpHeaders.ACCEPT)).isEqualTo(acceptType); +// return request; +// } +//} diff --git a/src/test/java/com/cdancy/jenkins/rest/BaseJenkinsTest.java b/src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsTest.java similarity index 57% rename from src/test/java/com/cdancy/jenkins/rest/BaseJenkinsTest.java rename to src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsTest.java index afced72..290fd02 100644 --- a/src/test/java/com/cdancy/jenkins/rest/BaseJenkinsTest.java +++ b/src/test/java/io/github/hmedioni/jenkins/client/BaseJenkinsTest.java @@ -15,24 +15,16 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest; +package io.github.hmedioni.jenkins.client; -import java.io.IOException; -import java.net.URL; -import java.util.Objects; -import java.util.Properties; +import io.github.hmedioni.jenkins.client.auth.*; +import io.github.hmedioni.jenkins.client.config.*; +import kotlin.text.*; -import org.jclouds.Constants; -import org.jclouds.ContextBuilder; -import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; -import static org.jclouds.util.Strings2.toStringAndClose; - -import com.cdancy.jenkins.rest.config.JenkinsAuthenticationModule; -import com.cdancy.jenkins.rest.auth.AuthenticationType; - -import com.google.common.base.Charsets; -import com.google.common.base.Throwables; -import com.google.common.collect.Lists; +import java.io.*; +import java.net.*; +import java.nio.charset.*; +import java.util.*; /** * Base class for Jenkins mock tests and some Live tests. @@ -50,14 +42,14 @@ public BaseJenkinsTest() { /** * Create API from passed URL. - * + *

    * The default authentication is the ApiToken, for it requires no crumb and simplifies mockTests expectations. * * @param url endpoint of instance. * @return instance of JenkinsApi. */ public JenkinsApi api(final URL url) { - return api(url, AuthenticationType.UsernameApiToken, USERNAME_APITOKEN); + return api(url, AuthenticationType.USERNAME_API_TOKEN, USERNAME_APITOKEN); } /** @@ -67,63 +59,53 @@ public JenkinsApi api(final URL url) { * @return instance of JenkinsApi. */ public JenkinsApi anonymousAuthApi(final URL url) { - return api(url, AuthenticationType.Anonymous, AuthenticationType.Anonymous.name().toLowerCase()); + return api(url, AuthenticationType.ANONYMOUS, AuthenticationType.ANONYMOUS.name().toLowerCase()); } /** * Create API for the given authentication type and string. * - * @param url the endpoint of the instance. - * @param authType the type of authentication. + * @param url the endpoint of the instance. + * @param authType the type of authentication. * @param authString the string to use as the credential. * @return instance of JenkinsApi. */ public JenkinsApi api(final URL url, final AuthenticationType authType, final String authString) { final JenkinsAuthentication creds = creds(authType, authString); - final JenkinsAuthenticationModule credsModule = new JenkinsAuthenticationModule(creds); - return ContextBuilder.newBuilder(provider) - .endpoint(url.toString()) - .overrides(setupProperties()) - .modules(Lists.newArrayList(credsModule, new SLF4JLoggingModule())) - .buildApi(JenkinsApi.class); + JenkinsProperties jenkinsProperties = new JenkinsProperties(url.toString() ,creds); + JenkinsClient jenkinsClient = JenkinsClient.create(jenkinsProperties); + return jenkinsClient.api(); } + /** * Create the Jenkins Authentication instance. * - * @param authType authentication type. Falls back to anonymous when null. + * @param authType authentication type. Falls back to anonymous when null. * @param authString the authentication string to use (username:password, username:apiToken, or base64 encoded). * @return an authentication instance. */ public JenkinsAuthentication creds(final AuthenticationType authType, final String authString) { - final JenkinsAuthentication.Builder authBuilder = JenkinsAuthentication.builder(); - if (authType == AuthenticationType.UsernamePassword) { + final JenkinsAuthentication.Builder authBuilder = new JenkinsAuthentication.Builder(); + if (authType == AuthenticationType.USERNAME_PASSWORD) { authBuilder.credentials(authString); - } else if (authType == AuthenticationType.UsernameApiToken) { + } else if (authType == AuthenticationType.USERNAME_API_TOKEN) { authBuilder.apiToken(authString); } // Anonymous authentication is the default when not specified return authBuilder.build(); } - protected Properties setupProperties() { - final Properties properties = new Properties(); - properties.setProperty(Constants.PROPERTY_MAX_RETRIES, "0"); - properties.setProperty(Constants.PROPERTY_CONNECTION_TIMEOUT, "60"); - return properties; - } - /** * Get the String representation of some resource to be used as payload. * - * @param resource - * String representation of a given resource + * @param resource String representation of a given resource * @return payload in String form */ - public String payloadFromResource(String resource) { + public String payloadFromResource(final String resource) { try { - return new String(toStringAndClose(Objects.requireNonNull(getClass().getResourceAsStream(resource))).getBytes(Charsets.UTF_8)); + return new String((getClass().getResourceAsStream(resource)).readAllBytes(), StandardCharsets.UTF_8); } catch (IOException e) { - throw Throwables.propagate(e); + throw new RuntimeException(e); } } } diff --git a/src/test/java/io/github/hmedioni/jenkins/client/JenkinsAuthenticationMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/JenkinsAuthenticationMockTest.java new file mode 100644 index 0000000..9e37058 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/JenkinsAuthenticationMockTest.java @@ -0,0 +1,118 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client; +// +//import io.github.hmedioni.jenkins.client.auth.*; +//import io.github.hmedioni.jenkins.client.exception.*; +//import org.testng.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +//public class JenkinsAuthenticationMockTest { +// +// @Test +// public void testAnonymousAuthentication() { +// JenkinsAuthentication ja = JenkinsAuthentication.builder().build(); +// assertEquals(ja.identity, "anonymous"); +// Assert.assertEquals(ja.authType(), AuthenticationType.Anonymous); +// assertEquals(ja.authValue(), base64().encode("anonymous:".getBytes())); +// assertEquals(ja.credential, ja.authValue()); +// } +// +// @Test +// public void testUsernamePasswordAuthentication() { +// JenkinsAuthentication ja = JenkinsAuthentication.builder() +// .credentials("user:password") +// .build(); +// assertEquals(ja.identity, "user"); +// Assert.assertEquals(ja.authType(), AuthenticationType.UsernamePassword); +// assertEquals(ja.authValue(), base64().encode("user:password".getBytes())); +// assertEquals(ja.credential, ja.authValue()); +// } +// +// @Test +// public void testUsernameApiTokenAuthentication() { +// JenkinsAuthentication ja = JenkinsAuthentication.builder() +// .apiToken("user:token") +// .build(); +// assertEquals(ja.identity, "user"); +// Assert.assertEquals(ja.authType(), AuthenticationType.UsernameApiToken); +// assertEquals(ja.authValue(), base64().encode("user:token".getBytes())); +// assertEquals(ja.credential, ja.authValue()); +// } +// +// @Test +// public void testEncodedUsernamePasswordAuthentication() { +// String encoded = base64().encode("user:password".getBytes()); +// JenkinsAuthentication ja = JenkinsAuthentication.builder() +// .credentials(encoded) +// .build(); +// assertEquals(ja.identity, "user"); +// Assert.assertEquals(ja.authType(), AuthenticationType.UsernamePassword); +// assertEquals(ja.authValue(), encoded); +// assertEquals(ja.credential, ja.authValue()); +// } +// +// @Test +// public void testEncodedUsernameApiTokenAuthentication() { +// String encoded = base64().encode("user:token".getBytes()); +// JenkinsAuthentication ja = JenkinsAuthentication.builder() +// .apiToken(encoded) +// .build(); +// assertEquals(ja.identity, "user"); +// Assert.assertEquals(ja.authType(), AuthenticationType.UsernameApiToken); +// assertEquals(ja.authValue(), encoded); +// assertEquals(ja.credential, ja.authValue()); +// } +// +// @Test +// public void testEmptyUsernamePassword() { +// JenkinsAuthentication ja = JenkinsAuthentication.builder() +// .credentials(":") +// .build(); +// assertEquals(ja.identity, ""); +// Assert.assertEquals(ja.authType(), AuthenticationType.UsernamePassword); +// assertEquals(ja.authValue(), base64().encode(":".getBytes())); +// assertEquals(ja.credential, ja.authValue()); +// } +// +// @Test +// public void testEmptyUsernameApiToken() { +// JenkinsAuthentication ja = JenkinsAuthentication.builder() +// .apiToken(":") +// .build(); +// assertEquals(ja.identity, ""); +// Assert.assertEquals(ja.authType(), AuthenticationType.UsernameApiToken); +// assertEquals(ja.authValue(), base64().encode(":".getBytes())); +// assertEquals(ja.credential, ja.authValue()); +// } +// +// @Test +// public void testUndetectableCredential() { +// String invalid = base64().encode("no_colon_here".getBytes()); +// try { +// JenkinsAuthentication.builder() +// .apiToken(invalid) +// .build(); +// } catch (UndetectableIdentityException ex) { +// assertEquals(ex.getMessage(), +// "Unable to detect the identity being used in '" + invalid + "'. Supported types are a user:password, or a user:apiToken, or their base64 encoded value."); +// } +// } +//} diff --git a/src/test/java/com/cdancy/jenkins/rest/TestUtilities.java b/src/test/java/io/github/hmedioni/jenkins/client/TestUtilities.java similarity index 85% rename from src/test/java/com/cdancy/jenkins/rest/TestUtilities.java rename to src/test/java/io/github/hmedioni/jenkins/client/TestUtilities.java index 7d992bd..449771d 100644 --- a/src/test/java/com/cdancy/jenkins/rest/TestUtilities.java +++ b/src/test/java/io/github/hmedioni/jenkins/client/TestUtilities.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.cdancy.jenkins.rest; +package io.github.hmedioni.jenkins.client; /** * Static methods for generating test data. @@ -28,6 +28,10 @@ public class TestUtilities extends JenkinsUtils { public static final String TEST_API_TOKEN_SYSTEM_PROPERTY = "test.jenkins.usernameApiToken"; public static final String TEST_API_TOKEN_ENVIRONMENT_VARIABLE = TEST_API_TOKEN_SYSTEM_PROPERTY.replaceAll("\\.", "_").toUpperCase(); + private TestUtilities() { + throw new UnsupportedOperationException("Purposefully not implemented"); + } + /** * Find credentials (ApiToken, UsernamePassword, or Anonymous) from system/environment. * @@ -35,12 +39,12 @@ public class TestUtilities extends JenkinsUtils { */ public static JenkinsAuthentication inferTestAuthentication() { - final JenkinsAuthentication.Builder inferAuth = JenkinsAuthentication.builder(); + final JenkinsAuthentication.Builder inferAuth = new JenkinsAuthentication.Builder(); // 1.) Check for API Token as this requires no crumb hence is faster String authValue = JenkinsUtils - .retriveExternalValue(TEST_API_TOKEN_SYSTEM_PROPERTY, - TEST_API_TOKEN_ENVIRONMENT_VARIABLE); + .retriveExternalValue(TEST_API_TOKEN_SYSTEM_PROPERTY, + TEST_API_TOKEN_ENVIRONMENT_VARIABLE); if (authValue != null) { inferAuth.apiToken(authValue); return inferAuth.build(); @@ -48,8 +52,8 @@ public static JenkinsAuthentication inferTestAuthentication() { // 2.) Check for UsernamePassword auth credentials. authValue = JenkinsUtils - .retriveExternalValue(TEST_CREDENTIALS_SYSTEM_PROPERTY, - TEST_CREDENTIALS_ENVIRONMENT_VARIABLE); + .retriveExternalValue(TEST_CREDENTIALS_SYSTEM_PROPERTY, + TEST_CREDENTIALS_ENVIRONMENT_VARIABLE); if (authValue != null) { inferAuth.credentials(authValue); return inferAuth.build(); @@ -58,8 +62,4 @@ public static JenkinsAuthentication inferTestAuthentication() { // 3.) If neither #1 or #2 find anything "Anonymous" access is assumed. return inferAuth.build(); } - - private TestUtilities() { - throw new UnsupportedOperationException("Purposefully not implemented"); - } } diff --git a/src/test/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApiLiveTest.java similarity index 70% rename from src/test/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApiLiveTest.java rename to src/test/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApiLiveTest.java index f08877f..2ae996e 100644 --- a/src/test/java/com/cdancy/jenkins/rest/features/ConfigurationAsCodeApiLiveTest.java +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApiLiveTest.java @@ -14,15 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.cdancy.jenkins.rest.features; +package io.github.hmedioni.jenkins.client.features; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.assertFalse; +import io.github.hmedioni.jenkins.client.*; +import io.github.hmedioni.jenkins.client.domain.common.*; +import org.testng.annotations.*; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest; +import static org.testng.Assert.*; @Test(groups = "live", testName = "ConfigurationAsCodeApiLiveTest", singleThreaded = true) public class ConfigurationAsCodeApiLiveTest extends BaseJenkinsApiLiveTest { @@ -30,29 +28,29 @@ public class ConfigurationAsCodeApiLiveTest extends BaseJenkinsApiLiveTest { @Test public void testCascCheck() { String config = payloadFromResource("/casc.yml"); - RequestStatus success = api().check(config); - assertTrue(success.value()); + RequestStatus success = api().check(config).getBody(); + assertTrue(success.getValue()); } @Test public void testCascApply() { String config = payloadFromResource("/casc.yml"); - RequestStatus success = api().apply(config); - assertTrue(success.value()); + RequestStatus success = api().apply(config).getBody(); + assertTrue(success.getValue()); } @Test public void testBadCascCheck() { String config = payloadFromResource("/casc-bad.yml"); - RequestStatus success = api().check(config); - assertFalse(success.value()); + RequestStatus success = api().check(config).getBody(); + assertFalse(success.getValue()); } @Test public void testBadCascApply() { String config = payloadFromResource("/casc-bad.yml"); - RequestStatus success = api().apply(config); - assertFalse(success.value()); + RequestStatus success = api().apply(config).getBody(); + assertFalse(success.getValue()); } private ConfigurationAsCodeApi api() { diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApiMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApiMockTest.java new file mode 100644 index 0000000..560e0cf --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/ConfigurationAsCodeApiMockTest.java @@ -0,0 +1,92 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import okhttp3.mockwebserver.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +///** +// * Mock tests for the {@link ConfigurationAsCodeApi} class. +// */ +//@Test(groups = "unit", testName = "ConfigurationAsCodeApiMockTest") +//public class ConfigurationAsCodeApiMockTest extends BaseJenkinsMockTest { +// +// public void testCascCheck() throws Exception { +// try (MockWebServer server = mockWebServer(); +// JenkinsApi jenkinsApi = api(server.url("/").url())) { +// server.enqueue(new MockResponse().setResponseCode(200)); +// +// ConfigurationAsCodeApi api = jenkinsApi.configurationAsCodeApi(); +// RequestStatus requestStatus = api.check("random"); +// System.out.println(requestStatus.errors()); +// assertNotNull(requestStatus); +// assertTrue(requestStatus.getValue()); +// assertEquals(requestStatus.errors().size(), 0); +// } +// } +// +// public void testCascApply() throws Exception { +// try (MockWebServer server = mockWebServer(); +// JenkinsApi jenkinsApi = api(server.url("/").url())) { +// server.enqueue(new MockResponse().setResponseCode(200)); +// +// ConfigurationAsCodeApi api = jenkinsApi.configurationAsCodeApi(); +// RequestStatus requestStatus = api.apply("random"); +// assertNotNull(requestStatus); +// assertTrue(requestStatus.getValue()); +// assertEquals(requestStatus.errors().size(), 0); +// } +// } +// +// public void testBadCascCheck() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(500)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// ConfigurationAsCodeApi api = jenkinsApi.configurationAsCodeApi(); +// try { +// RequestStatus requestStatus = api.check("random"); +// assertNotNull(requestStatus); +// assertFalse(requestStatus.getValue()); +// assertEquals(requestStatus.errors().size(), 1); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testBadCascApply() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(500)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// ConfigurationAsCodeApi api = jenkinsApi.configurationAsCodeApi(); +// try { +// RequestStatus requestStatus = api.apply("random"); +// assertNotNull(requestStatus); +// assertFalse(requestStatus.getValue()); +// assertEquals(requestStatus.errors().size(), 1); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApiLiveTest.java new file mode 100644 index 0000000..b736f02 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApiLiveTest.java @@ -0,0 +1,39 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.crumb.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +//@Test(groups = "live", testName = "CrumbIssuerApiLiveTest", singleThreaded = true) +//public class CrumbIssuerApiLiveTest extends BaseJenkinsApiLiveTest { +// +// @Test +// public void testGetCrumb() { +// final Crumb crumb = api().crumb(); +// assertNotNull(crumb); +// assertNotNull(crumb.getValue()); +// assertTrue(crumb.errors().isEmpty()); +// } +// +// private CrumbIssuerApi api() { +// return api.crumbIssuerApi(); +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApiMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApiMockTest.java new file mode 100644 index 0000000..fb69855 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/CrumbIssuerApiMockTest.java @@ -0,0 +1,50 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.crumb.*; +//import okhttp3.mockwebserver.*; +//import org.springframework.http.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +///** +// * Mock tests for the {@link CrumbIssuerApi} class. +// */ +//@Test(groups = "unit", testName = "CrumbIssuerApiMockTest") +//public class CrumbIssuerApiMockTest extends BaseJenkinsMockTest { +// +// public void testGetSystemInfo() throws Exception { +// MockWebServer server = mockWebServer(); +// +// final String value = "04a1109fc2db171362c966ebe9fc87f0"; +// server.enqueue(new MockResponse().setBody("Jenkins-Crumb:" + value).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// CrumbIssuerApi api = jenkinsApi.crumbIssuerApi(); +// try { +// final Crumb instance = api.crumb(null).getBody(); +// assertNotNull(instance); +// assertEquals(instance.getValue(), value); +// assertSentAccept(server, "GET", "/crumbIssuer/api/xml?xpath=concat%28//crumbRequestField,%22%3A%22,//crumb%29", MediaType.TEXT_PLAIN); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/JobsApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/JobsApiLiveTest.java new file mode 100644 index 0000000..f04c642 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/JobsApiLiveTest.java @@ -0,0 +1,679 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.job.*; +//import io.github.hmedioni.jenkins.client.domain.plugins.*; +//import io.github.hmedioni.jenkins.client.domain.queue.*; +//import org.testng.annotations.*; +// +//import java.util.*; +// +//import static org.testng.Assert.*; +// +//@Test(groups = "live", testName = "JobsApiLiveTest", singleThreaded = true) +//public class JobsApiLiveTest extends BaseJenkinsApiLiveTest { +// +// private static final String FOLDER_PLUGIN_NAME = "cloudbees-folder"; +// private static final String FOLDER_PLUGIN_VERSION = "latest"; +// private static final String FREESTYLE_JOB_NAME = "FreeStyleSleep"; +// private static final String PIPELINE_JOB_NAME = "PipelineSleep"; +// private static final String PIPELINE_WITH_ACTION_JOB_NAME = "PipelineAction"; +// private IntegerResponse queueId; +// private IntegerResponse queueIdForAnotherJob; +// private Integer buildNumber; +// +// @Test +// public void testCreateJob() { +// String config = payloadFromResource("/freestyle-project-no-params.xml"); +// RequestStatus success = api().create(null, "DevTest", config); +// assertTrue(success.getValue()); +// } +// +// // The next 3 tests must run one after the other as they use the same Job +// @Test +// public void testStopFreeStyleBuild() throws InterruptedException { +// String config = payloadFromResource("/freestyle-project-sleep-10-task.xml"); +// RequestStatus createStatus = api().create(null, FREESTYLE_JOB_NAME, config); +// assertTrue(createStatus.getValue()); +// IntegerResponse qId = api().build(null, FREESTYLE_JOB_NAME); +// assertNotNull(qId); +// assertTrue(qId.getValue() > 0); +// QueueItem queueItem = getRunningQueueItem(qId.getValue()); +// assertNotNull(queueItem); +// assertNotNull(queueItem.executable()); +// assertNotNull(queueItem.executable().number()); +// RequestStatus stopStatus = api().stop(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); +// assertTrue(stopStatus.getValue()); +// BuildInfo buildInfo = getCompletedBuild(FREESTYLE_JOB_NAME, queueItem); +// assertEquals(buildInfo.result(), "ABORTED"); +// } +// +// @Test(dependsOnMethods = "testStopFreeStyleBuild") +// public void testTermFreeStyleBuild() throws InterruptedException { +// IntegerResponse qId = api().build(null, FREESTYLE_JOB_NAME); +// assertNotNull(qId); +// assertTrue(qId.getValue() > 0); +// QueueItem queueItem = getRunningQueueItem(qId.getValue()); +// assertNotNull(queueItem); +// assertNotNull(queueItem.executable()); +// assertNotNull(queueItem.executable().number()); +// RequestStatus termStatus = api().term(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); +// // Strangely, term does not work on FreeStyleBuild +// assertFalse(termStatus.getValue()); +// assertEquals(termStatus.errors().size(), 1); +// assertEquals(termStatus.errors().get(0).message(), "The term operation does not exist for " + +// System.getProperty("test.jenkins.endpoint") + +// "/job/" + FREESTYLE_JOB_NAME + "/" + queueItem.executable().number() + "/term/, try stop instead."); +// assertEquals(termStatus.errors().get(0).exceptionName(), "com.cdancy.jenkins.rest.exception.RedirectTo404Exception"); +// api().stop(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); +// BuildInfo buildInfoStop = getCompletedBuild(FREESTYLE_JOB_NAME, queueItem); +// assertEquals(buildInfoStop.result(), "ABORTED"); +// } +// +// @Test(dependsOnMethods = "testTermFreeStyleBuild") +// public void testKillFreeStyleBuild() throws InterruptedException { +// IntegerResponse qId = api().build(null, FREESTYLE_JOB_NAME); +// assertNotNull(qId); +// assertTrue(qId.getValue() > 0); +// QueueItem queueItem = getRunningQueueItem(qId.getValue()); +// assertNotNull(queueItem); +// assertNotNull(queueItem.executable()); +// assertNotNull(queueItem.executable().number()); +// RequestStatus killStatus = api().kill(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); +// // Strangely, kill does not work on FreeStyleBuild +// assertFalse(killStatus.getValue()); +// assertEquals(killStatus.errors().size(), 1); +// assertEquals(killStatus.errors().get(0).message(), "The kill operation does not exist for " + +// System.getProperty("test.jenkins.endpoint") + +// "/job/" + FREESTYLE_JOB_NAME + "/" + queueItem.executable().number() + "/kill/, try stop instead."); +// assertEquals(killStatus.errors().get(0).exceptionName(), "com.cdancy.jenkins.rest.exception.RedirectTo404Exception"); +// api().stop(null, FREESTYLE_JOB_NAME, queueItem.executable().number()); +// BuildInfo buildInfoStop = getCompletedBuild(FREESTYLE_JOB_NAME, queueItem); +// assertEquals(buildInfoStop.result(), "ABORTED"); +// +// // Delete the job, it's no longer needed +// RequestStatus success = api().delete(null, FREESTYLE_JOB_NAME); +// assertNotNull(success); +// assertTrue(success.getValue()); +// } +// +// // The next 3 tests must run one after the other as they use the same Job +// @Test +// public void testStopPipelineBuild() throws InterruptedException { +// String config = payloadFromResource("/pipeline.xml"); +// RequestStatus createStatus = api().create(null, PIPELINE_JOB_NAME, config); +// assertTrue(createStatus.getValue()); +// IntegerResponse qId = api().build(null, PIPELINE_JOB_NAME); +// assertNotNull(qId); +// assertTrue(qId.getValue() > 0); +// QueueItem queueItem = getRunningQueueItem(qId.getValue()); +// assertNotNull(queueItem); +// assertNotNull(queueItem.executable()); +// assertNotNull(queueItem.executable().number()); +// RequestStatus stopStatus = api().stop(null, PIPELINE_JOB_NAME, queueItem.executable().number()); +// assertTrue(stopStatus.getValue()); +// BuildInfo buildInfo = getCompletedBuild(PIPELINE_JOB_NAME, queueItem); +// assertEquals(buildInfo.result(), "ABORTED"); +// } +// +// @Test(dependsOnMethods = "testStopPipelineBuild") +// public void testTermPipelineBuild() throws InterruptedException { +// IntegerResponse qId = api().build(null, PIPELINE_JOB_NAME); +// assertNotNull(qId); +// assertTrue(qId.getValue() > 0); +// QueueItem queueItem = getRunningQueueItem(qId.getValue()); +// assertNotNull(queueItem); +// assertNotNull(queueItem.executable()); +// assertNotNull(queueItem.executable().number()); +// RequestStatus termStatus = api().term(null, PIPELINE_JOB_NAME, queueItem.executable().number()); +// assertTrue(termStatus.getValue()); +// BuildInfo buildInfo = getCompletedBuild(PIPELINE_JOB_NAME, queueItem); +// assertEquals(buildInfo.result(), "ABORTED"); +// } +// +// @Test(dependsOnMethods = "testTermPipelineBuild") +// public void testKillPipelineBuild() throws InterruptedException { +// IntegerResponse qId = api().build(null, PIPELINE_JOB_NAME); +// assertNotNull(qId); +// assertTrue(qId.getValue() > 0); +// QueueItem queueItem = getRunningQueueItem(qId.getValue()); +// assertNotNull(queueItem); +// assertNotNull(queueItem.executable()); +// assertNotNull(queueItem.executable().number()); +// RequestStatus killStatus = api().kill(null, PIPELINE_JOB_NAME, queueItem.executable().number()); +// assertTrue(killStatus.getValue()); +// BuildInfo buildInfo = getCompletedBuild(PIPELINE_JOB_NAME, queueItem); +// assertEquals(buildInfo.result(), "ABORTED"); +// +// // The Job is no longer needed, delete it. +// RequestStatus success = api().delete(null, PIPELINE_JOB_NAME); +// assertNotNull(success); +// assertTrue(success.getValue()); +// } +// +// @Test(dependsOnMethods = {"testCreateJob", "testCreateJobForEmptyAndNullParams", "testKillPipelineBuild", "testKillFreeStyleBuild", "testDeleteFolders"}) +// public void testGetJobListFromRoot() { +// JobList output = api().jobList(""); +// assertNotNull(output); +// assertFalse(output.jobs().isEmpty()); +// assertEquals(output.jobs().size(), 2); +// } +// +// @Test(dependsOnMethods = "testCreateJob") +// public void testGetJobInfo() { +// JobInfo output = api().jobInfo(null, "DevTest"); +// assertNotNull(output); +// assertEquals(output.name(), "DevTest"); +// assertNull(output.lastBuild()); +// assertNull(output.firstBuild()); +// assertTrue(output.builds().isEmpty()); +// } +// +// @Test(dependsOnMethods = "testGetJobInfo") +// public void testLastBuildNumberOnJobWithNoBuilds() { +// Integer output = api().lastBuildNumber(null, "DevTest"); +// assertNull(output); +// } +// +// @Test(dependsOnMethods = "testLastBuildNumberOnJobWithNoBuilds") +// public void testLastBuildTimestampOnJobWithNoBuilds() { +// String output = api().lastBuildTimestamp(null, "DevTest"); +// assertNull(output); +// } +// +// @Test(dependsOnMethods = "testLastBuildTimestampOnJobWithNoBuilds") +// public void testBuildJob() throws InterruptedException { +// queueId = api().build(null, "DevTest"); +// assertNotNull(queueId); +// assertTrue(queueId.getValue() > 0); +// assertEquals(queueId.errors().size(), 0); +// // Before we exit the test, wait until the job runs +// QueueItem queueItem = getRunningQueueItem(queueId.getValue()); +// getCompletedBuild("DevTest", queueItem); +// } +// +// @Test(dependsOnMethods = "testBuildJob") +// public void testLastBuildNumberOnJob() { +// buildNumber = api().lastBuildNumber(null, "DevTest"); +// assertNotNull(buildNumber); +// assertEquals((int) buildNumber, 1); +// } +// +// @Test(dependsOnMethods = "testLastBuildNumberOnJob") +// public void testLastBuildTimestamp() { +// String output = api().lastBuildTimestamp(null, "DevTest"); +// assertNotNull(output); +// } +// +// @Test(dependsOnMethods = "testLastBuildTimestamp") +// public void testLastBuildGetProgressiveText() { +// ProgressiveText output = api().progressiveText(null, "DevTest", 0); +// assertNotNull(output); +// assertTrue(output.size() > 0); +// assertFalse(output.hasMoreData()); +// } +// +// @Test(dependsOnMethods = "testLastBuildGetProgressiveText") +// public void testGetBuildInfo() { +// BuildInfo output = api().buildInfo(null, "DevTest", buildNumber); +// assertNotNull(output); +// assertEquals("DevTest #" + buildNumber, output.fullDisplayName()); +// assertEquals((int) queueId.getValue(), output.queueId()); +// } +// +// @Test(dependsOnMethods = "testGetBuildInfo") +// public void testGetBuildParametersOfLastJob() { +// List parameters = api().buildInfo(null, "DevTest", 1).actions().get(0).parameters(); +// assertEquals(parameters.size(), 0); +// } +// +// @Test +// public void testBuildInfoActions() throws InterruptedException { +// String config = payloadFromResource("/pipeline-with-action.xml"); +// RequestStatus createStatus = api().create(null, PIPELINE_WITH_ACTION_JOB_NAME, config); +// assertTrue(createStatus.getValue()); +// IntegerResponse qId = api().build(null, PIPELINE_WITH_ACTION_JOB_NAME); +// assertNotNull(qId); +// assertTrue(qId.getValue() > 0); +// QueueItem queueItem = getRunningQueueItem(qId.getValue()); +// assertNotNull(queueItem); +// assertNotNull(queueItem.executable()); +// assertNotNull(queueItem.executable().number()); +// BuildInfo buildInfo = getCompletedBuild(PIPELINE_WITH_ACTION_JOB_NAME, queueItem); +// assertEquals(buildInfo.result(), "SUCCESS"); +// System.out.println(buildInfo); +// boolean found = false; +// for (int idx = 0; idx < buildInfo.actions().size(); idx++) { +// if (buildInfo.actions().get(idx).text() != null) { +// if (buildInfo.actions().get(idx).text().equals("Hudson, we have a problem.") && +// buildInfo.actions().get(idx).iconPath().equals("error.svg") && +// buildInfo.actions().get(idx)._class().equals("com.jenkinsci.plugins.badge.action.BadgeSummaryAction")) { +// found = true; +// } +// } +// } +// assertTrue(found); +// +// // The Job is no longer needed, delete it. +// RequestStatus success = api().delete(null, PIPELINE_WITH_ACTION_JOB_NAME); +// assertNotNull(success); +// assertTrue(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testGetBuildParametersOfLastJob") +// public void testCreateJobThatAlreadyExists() { +// String config = payloadFromResource("/freestyle-project.xml"); +// RequestStatus success = api().create(null, "DevTest", config); +// assertFalse(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testCreateJobThatAlreadyExists") +// public void testSetDescription() { +// boolean success = api().description(null, "DevTest", "RandomDescription"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testSetDescription") +// public void testGetDescription() { +// String output = api().description(null, "DevTest"); +// assertEquals(output, "RandomDescription"); +// } +// +// @Test(dependsOnMethods = "testGetDescription") +// public void testGetConfig() { +// String output = api().config(null, "DevTest"); +// assertNotNull(output); +// } +// +// @Test(dependsOnMethods = "testGetConfig") +// public void testUpdateConfig() { +// String config = payloadFromResource("/freestyle-project.xml"); +// boolean success = api().config(null, "DevTest", config); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testUpdateConfig") +// public void testBuildJobWithParameters() { +// Map> params = new HashMap<>(); +// params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); +// IntegerResponse output = api().buildWithParameters(null, "DevTest", params); +// assertNotNull(output); +// assertTrue(output.getValue() > 0); +// assertEquals(output.errors().size(), 0); +// } +// +// @Test(dependsOnMethods = "testBuildJobWithParameters") +// public void testBuildJobWithNullParametersMap() { +// IntegerResponse output = api().buildWithParameters(null, "DevTest", null); +// assertNotNull(output); +// assertTrue(output.getValue() > 0); +// assertEquals(output.errors().size(), 0); +// } +// +// @Test(dependsOnMethods = "testBuildJobWithNullParametersMap") +// public void testBuildJobWithEmptyParametersMap() { +// IntegerResponse output = api().buildWithParameters(null, "DevTest", new HashMap<>()); +// assertNotNull(output); +// assertNull(output.getValue()); +// assertEquals(output.errors().size(), 1); +// } +// +// @Test(dependsOnMethods = "testBuildJobWithEmptyParametersMap") +// public void testDisableJob() { +// boolean success = api().disable(null, "DevTest"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testDisableJob") +// public void testDisableJobAlreadyDisabled() { +// boolean success = api().disable(null, "DevTest"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testDisableJobAlreadyDisabled") +// public void testEnableJob() { +// boolean success = api().enable(null, "DevTest"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testEnableJob") +// public void testEnableJobAlreadyEnabled() { +// boolean success = api().enable(null, "DevTest"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testEnableJobAlreadyEnabled") +// public void testRenameJob() { +// boolean success = api().rename(null, "DevTest", "NewDevTest"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testRenameJob") +// public void testRenameJobNotExist() { +// boolean success = api().rename(null, "JobNotExist", "NewDevTest"); +// assertFalse(success); +// } +// +// @Test(dependsOnMethods = "testRenameJobNotExist") +// public void testDeleteJob() { +// RequestStatus success = api().delete(null, "NewDevTest"); +// assertNotNull(success); +// assertTrue(success.getValue()); +// } +// +// // +// // check for the presence of folder-plugin +// // If not present, attempt to install it. +// // +// @Test +// public void testInstallFolderPlugin() throws Exception { +// long endTime = 0; +// long maxWaitTime = 5 * 60 * 1000; +// if (!isFolderPluginInstalled()) { +// RequestStatus status = api.pluginManagerApi().installNecessaryPlugins(FOLDER_PLUGIN_NAME + "@" + FOLDER_PLUGIN_VERSION); +// assertTrue(status.getValue()); +// while (endTime <= maxWaitTime) { +// if (!isFolderPluginInstalled()) { +// Thread.sleep(10000); +// endTime += 10000; +// } else { +// break; +// } +// } +// } +// assertTrue(isFolderPluginInstalled()); +// } +// +// @Test(dependsOnMethods = "testInstallFolderPlugin") +// public void testCreateFoldersInJenkins() { +// String config = payloadFromResource("/folder-config.xml"); +// RequestStatus success1 = api().create(null, "test-folder", config); +// assertTrue(success1.getValue()); +// RequestStatus success2 = api().create("test-folder", "test-folder-1", config); +// assertTrue(success2.getValue()); +// } +// +// @Test(dependsOnMethods = "testCreateFoldersInJenkins") +// public void testCreateJobInFolder() { +// String config = payloadFromResource("/freestyle-project-no-params.xml"); +// RequestStatus success = api().create("test-folder/test-folder-1", "JobInFolder", config); +// assertTrue(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testCreateFoldersInJenkins") +// public void testCreateJobWithIncorrectFolderPath() { +// String config = payloadFromResource("/folder-config.xml"); +// RequestStatus success = api().create("/test-folder//test-folder-1/", "Job", config); +// assertFalse(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testCreateJobInFolder") +// public void testGetJobListInFolder() { +// JobList output = api().jobList("test-folder/test-folder-1"); +// assertNotNull(output); +// assertFalse(output.jobs().isEmpty()); +// assertEquals(output.jobs().size(), 1); +// assertEquals(output.jobs().get(0), Job.create("hudson.model.FreeStyleProject", "JobInFolder", System.getProperty("test.jenkins.endpoint") + "/job/test-folder/job/test-folder-1/job/JobInFolder/", "notbuilt")); +// } +// +// @Test(dependsOnMethods = "testCreateJobInFolder") +// public void testUpdateJobConfigInFolder() { +// String config = payloadFromResource("/freestyle-project.xml"); +// boolean success = api().config("test-folder/test-folder-1", "JobInFolder", config); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testUpdateJobConfigInFolder") +// public void testDisableJobInFolder() { +// boolean success = api().disable("test-folder/test-folder-1", "JobInFolder"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testDisableJobInFolder") +// public void testEnableJobInFolder() { +// boolean success = api().enable("test-folder/test-folder-1", "JobInFolder"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testEnableJobInFolder") +// public void testSetDescriptionOfJobInFolder() { +// boolean success = api().description("test-folder/test-folder-1", "JobInFolder", "RandomDescription"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testSetDescriptionOfJobInFolder") +// public void testGetDescriptionOfJobInFolder() { +// String output = api().description("test-folder/test-folder-1", "JobInFolder"); +// assertEquals(output, "RandomDescription"); +// } +// +// @Test(dependsOnMethods = "testGetDescriptionOfJobInFolder") +// public void testGetJobInfoInFolder() { +// JobInfo output = api().jobInfo("test-folder/test-folder-1", "JobInFolder"); +// assertNotNull(output); +// assertEquals(output.name(), "JobInFolder"); +// assertTrue(output.builds().isEmpty()); +// } +// +// @Test(dependsOnMethods = "testGetJobInfoInFolder") +// public void testBuildWithParameters() throws InterruptedException { +// Map> params = new HashMap<>(); +// params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); +// queueIdForAnotherJob = api().buildWithParameters("test-folder/test-folder-1", "JobInFolder", params); +// assertNotNull(queueIdForAnotherJob); +// assertTrue(queueIdForAnotherJob.getValue() > 0); +// QueueItem queueItem = getRunningQueueItem(queueIdForAnotherJob.getValue()); +// assertNotNull(queueItem); +// } +// +// @Test(dependsOnMethods = "testBuildWithParameters") +// public void testLastBuildTimestampOfJobInFolder() { +// String output = api().lastBuildTimestamp("test-folder/test-folder-1", "JobInFolder"); +// assertNotNull(output); +// } +// +// @Test(dependsOnMethods = "testLastBuildTimestampOfJobInFolder") +// public void testGetProgressiveText() { +// ProgressiveText output = api().progressiveText("test-folder/test-folder-1", "JobInFolder", 0); +// assertNotNull(output); +// assertTrue(output.size() > 0); +// assertFalse(output.hasMoreData()); +// } +// +// @Test(dependsOnMethods = "testGetProgressiveText") +// public void testGetBuildInfoOfJobInFolder() { +// BuildInfo output = api().buildInfo("test-folder/test-folder-1", "JobInFolder", 1); +// assertNotNull(output); +// assertTrue(output.fullDisplayName().contains("JobInFolder #1")); +// assertEquals((int) queueIdForAnotherJob.getValue(), output.queueId()); +// } +// +// @Test(dependsOnMethods = "testGetProgressiveText") +// public void testGetBuildParametersofJob() { +// List parameters = api().buildInfo("test-folder/test-folder-1", "JobInFolder", 1).actions().get(0).parameters(); +// assertNotNull(parameters); +// assertEquals(parameters.get(0).name(), "SomeKey"); +// assertEquals(parameters.get(0).getValue(), "SomeVeryNewValue"); +// } +// +// @Test(dependsOnMethods = "testGetProgressiveText") +// public void testGetBuildCausesOfJob() { +// List causes = api().buildInfo("test-folder/test-folder-1", "JobInFolder", 1).actions().get(1).causes(); +// assertNotNull(causes); +// assertTrue(causes.size() > 0); +// assertNotNull(causes.get(0).shortDescription()); +// assertNotNull(causes.get(0).userId()); +// assertNotNull(causes.get(0).userName()); +// } +// +// @Test(dependsOnMethods = "testGetProgressiveText") +// public void testGetProgressiveTextOfBuildNumber() { +// ProgressiveText output = api().progressiveText("test-folder/test-folder-1", "JobInFolder", 1, 0); +// assertNotNull(output); +// assertTrue(output.size() > 0); +// assertFalse(output.hasMoreData()); +// } +// +// @Test +// public void testCreateJobForEmptyAndNullParams() { +// String config = payloadFromResource("/freestyle-project-empty-and-null-params.xml"); +// RequestStatus success = api().create(null, "JobForEmptyAndNullParams", config); +// assertTrue(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testCreateJobForEmptyAndNullParams") +// public void testBuildWithParametersOfJobForEmptyAndNullParams() throws InterruptedException { +// Map> params = new HashMap<>(); +// params.put("SomeKey1", Lists.newArrayList("")); +// params.put("SomeKey2", null); +// IntegerResponse job1 = api.jobsApi().buildWithParameters(null, "JobForEmptyAndNullParams", params); +// assertNotNull(job1); +// assertTrue(job1.getValue() > 0); +// assertEquals(job1.errors().size(), 0); +// QueueItem queueItem = getRunningQueueItem(job1.getValue()); +// assertNotNull(queueItem); +// } +// +// @Test(dependsOnMethods = "testBuildWithParametersOfJobForEmptyAndNullParams") +// public void testGetBuildParametersOfJobForEmptyAndNullParams() { +// List parameters = api().buildInfo(null, "JobForEmptyAndNullParams", 1).actions().get(0).parameters(); +// assertNotNull(parameters); +// assertEquals(parameters.get(0).name(), "SomeKey1"); +// assertTrue(parameters.get(0).getValue().isEmpty()); +// assertEquals(parameters.get(1).name(), "SomeKey2"); +// assertTrue(parameters.get(1).getValue().isEmpty()); +// } +// +// @Test(dependsOnMethods = {"testGetBuildParametersOfJobForEmptyAndNullParams", "testGetJobListFromRoot"}) +// public void testDeleteJobForEmptyAndNullParams() { +// RequestStatus success = api().delete(null, "JobForEmptyAndNullParams"); +// assertTrue(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testCreateFoldersInJenkins") +// public void testCreateJobWithLeadingAndTrailingForwardSlashes() { +// String config = payloadFromResource("/freestyle-project-no-params.xml"); +// RequestStatus success = api().create("/test-folder/test-folder-1/", "Job", config); +// assertTrue(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testCreateJobWithLeadingAndTrailingForwardSlashes") +// public void testDeleteJobWithLeadingAndTrailingForwardSlashes() { +// RequestStatus success = api().delete("/test-folder/test-folder-1/", "Job"); +// assertTrue(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testGetBuildInfoOfJobInFolder") +// public void testRenameJonInFloder() { +// boolean success = api().rename("test-folder/test-folder-1", "JobInFolder", "NewJobInFolder"); +// assertTrue(success); +// } +// +// @Test(dependsOnMethods = "testRenameJonInFloder") +// public void testDeleteJobInFolder() { +// RequestStatus success = api().delete("test-folder/test-folder-1", "NewJobInFolder"); +// assertTrue(success.getValue()); +// } +// +// @Test(dependsOnMethods = "testDeleteJobInFolder") +// public void testDeleteFolders() { +// RequestStatus success1 = api().delete("test-folder", "test-folder-1"); +// assertTrue(success1.getValue()); +// RequestStatus success2 = api().delete(null, "test-folder"); +// assertTrue(success2.getValue()); +// } +// +// @Test +// public void testGetJobInfoNonExistentJob() { +// JobInfo output = api().jobInfo(null, randomString()); +// assertNull(output); +// } +// +// @Test +// public void testDeleteJobNonExistent() { +// RequestStatus success = api().delete(null, randomString()); +// assertNotNull(success); +// assertFalse(success.getValue()); +// } +// +// @Test +// public void testGetConfigNonExistentJob() { +// String output = api().config(null, randomString()); +// assertNull(output); +// } +// +// @Test +// public void testSetDescriptionNonExistentJob() { +// boolean success = api().description(null, randomString(), "RandomDescription"); +// assertFalse(success); +// } +// +// @Test +// public void testGetDescriptionNonExistentJob() { +// String output = api().description(null, randomString()); +// assertNull(output); +// } +// +// @Test +// public void testBuildNonExistentJob() { +// IntegerResponse output = api().build(null, randomString()); +// assertNotNull(output); +// assertNull(output.getValue()); +// assertTrue(output.errors().size() > 0); +// assertNotNull(output.errors().get(0).context()); +// assertNotNull(output.errors().get(0).message()); +// assertEquals(output.errors().get(0).exceptionName(), "org.jclouds.rest.ResourceNotFoundException"); +// } +// +// @Test +// public void testGetBuildInfoNonExistentJob() { +// BuildInfo output = api().buildInfo(null, randomString(), 123); +// assertNull(output); +// } +// +// @Test +// public void testBuildNonExistentJobWithParams() { +// Map> params = new HashMap<>(); +// params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); +// IntegerResponse output = api().buildWithParameters(null, randomString(), params); +// assertNotNull(output); +// assertNull(output.getValue()); +// assertTrue(output.errors().size() > 0); +// assertNotNull(output.errors().get(0).context()); +// assertNotNull(output.errors().get(0).message()); +// assertEquals(output.errors().get(0).exceptionName(), "org.jclouds.rest.ResourceNotFoundException"); +// } +// +// private boolean isFolderPluginInstalled() { +// boolean installed = false; +// Plugins plugins = api.pluginManagerApi().plugins(3, null); +// for (Plugin plugin : plugins.plugins()) { +// if (plugin.shortName().equals(FOLDER_PLUGIN_NAME)) { +// installed = true; +// break; +// } +// } +// return installed; +// } +// +// private JobsApi api() { +// return api.jobsApi(); +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/JobsApiMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/JobsApiMockTest.java new file mode 100644 index 0000000..7cbc4e0 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/JobsApiMockTest.java @@ -0,0 +1,1131 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.job.*; +//import okhttp3.mockwebserver.*; +//import org.springframework.http.*; +//import org.testng.annotations.*; +// +//import java.util.*; +// +//import static org.testng.Assert.*; +// +///** +// * Mock tests for the {@link JobsApi} class. +// */ +//@Test(groups = "unit", testName = "JobsApiMockTest") +//public class JobsApiMockTest extends BaseJenkinsMockTest { +// +// public void testGetInnerFolderJobList() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/jobsInJenkinsFolder.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// JobList output = api.jobList("Folder1/Folder 2"); +// assertNotNull(output); +// assertNotNull(output.jobs()); +// assertEquals(output.jobs().size(), 1); +// assertEquals(output.jobs().get(0), Job.create("hudson.model.FreeStyleProject", "Test Project", "http://localhost:8080/job/username", null)); +// assertSent(server, "GET", "/job/Folder1/job/Folder%202/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetRootFolderJobList() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/jobsInRootFolder.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// JobList output = api.jobList(""); +// assertNotNull(output); +// assertNotNull(output.jobs()); +// assertEquals(output.jobs().size(), 6); +// assertSent(server, "GET", "/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetJobInfo() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/job-info.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// JobInfo output = api.jobInfo(null, "fish"); +// assertNotNull(output); +// assertEquals(output.name(), "fish"); +// assertEquals(output.builds().size(), 7); +// assertSent(server, "GET", "/job/fish/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetJobInfoNotFound() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// JobInfo output = api.jobInfo(null, "fish"); +// assertNull(output); +// assertSent(server, "GET", "/job/fish/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetBuildInfo() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/build-info.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// BuildInfo output = api.buildInfo(null, "fish", 10); +// assertNotNull(output); +// assertEquals(output.fullDisplayName(), "fish #10"); +// assertEquals(output.artifacts().size(), 1); +// assertEquals(output.actions().size(), 5); +// assertEquals(output.actions().get(2).text(), "There could be HTML text here"); +// assertEquals(output.actions().get(2).iconPath(), "clipboard.png"); +// assertEquals(output.actions().get(2)._class(), "com.jenkinsci.plugins.badge.action.BadgeSummaryAction"); +// assertEquals(output.actions().get(3).text(), null); +// assertEquals(output.actions().get(4)._class(), "org.jenkinsci.plugins.displayurlapi.actions.RunDisplayAction"); +// assertSent(server, "GET", "/job/fish/10/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetBuildInfoNotFound() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// BuildInfo output = api.buildInfo(null, "fish", 10); +// assertNull(output); +// assertSent(server, "GET", "/job/fish/10/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testCreateJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String configXML = payloadFromResource("/freestyle-project.xml"); +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus success = api.create(null, "DevTest", configXML); +// assertNotNull(success); +// assertTrue(success.getValue()); +// assertTrue(success.errors().isEmpty()); +// assertSentWithXMLFormDataAccept(server, "POST", "/createItem?name=DevTest", configXML, MediaType.WILDCARD); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testCreateJobInFolder() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String configXML = payloadFromResource("/freestyle-project.xml"); +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus success = api.create("test-folder", "JobInFolder", configXML); +// assertNotNull(success); +// assertTrue(success.getValue()); +// assertTrue(success.errors().isEmpty()); +// assertSentWithXMLFormDataAccept(server, "POST", "/job/test-folder/createItem?name=JobInFolder", configXML, MediaType.WILDCARD); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testSimpleFolderPathWithLeadingAndTrailingForwardSlashes() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String configXML = payloadFromResource("/freestyle-project.xml"); +// server.enqueue(new MockResponse().setResponseCode(200)); +// +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus success = api.create("/test-folder/test-folder-1/", "JobInFolder", configXML); +// assertNotNull(success); +// assertTrue(success.getValue()); +// assertTrue(success.errors().isEmpty()); +// assertSentWithXMLFormDataAccept(server, "POST", "/job/test-folder/job/test-folder-1/createItem?name=JobInFolder", configXML, MediaType.WILDCARD); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testCreateJobAlreadyExists() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String configXML = payloadFromResource("/freestyle-project.xml"); +// server.enqueue(new MockResponse().setHeader("X-Error", "A job already exists with the name ?DevTest?") +// .setResponseCode(400)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus success = api.create(null, "DevTest", configXML); +// assertNotNull(success); +// assertFalse(success.getValue()); +// assertFalse(success.errors().isEmpty()); +// assertSentWithXMLFormDataAccept(server, "POST", "/createItem?name=DevTest", configXML, MediaType.WILDCARD); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetDescription() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setBody("whatever").setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// String output = api.description(null, "DevTest"); +// assertNotNull(output); +// assertEquals(output, "whatever"); +// assertSentAcceptText(server, "GET", "/job/DevTest/description"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetDescriptionNonExistentJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// String output = api.description(null, "DevTest"); +// assertNull(output); +// assertSentAcceptText(server, "GET", "/job/DevTest/description"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testUpdateDescription() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.description(null, "DevTest", "whatever"); +// assertTrue(success); +// assertSentWithFormData(server, "POST", "/job/DevTest/description", "description=whatever", +// MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testUpdateDescriptionNonExistentJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.description(null, "DevTest", "whatever"); +// assertFalse(success); +// assertSentWithFormData(server, "POST", "/job/DevTest/description", "description=whatever", +// MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetConfig() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String configXML = payloadFromResource("/freestyle-project.xml"); +// server.enqueue(new MockResponse().setBody(configXML).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// String output = api.config(null, "DevTest"); +// assertNotNull(output); +// assertEquals(output, configXML); +// assertSentAcceptText(server, "GET", "/job/DevTest/config.xml"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetConfigNonExistentJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// String output = api.config(null, "DevTest"); +// assertNull(output); +// assertSentAcceptText(server, "GET", "/job/DevTest/config.xml"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testUpdateConfig() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String configXML = payloadFromResource("/freestyle-project.xml"); +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.config(null, "DevTest", configXML); +// assertTrue(success); +// assertSentAccept(server, "POST", "/job/DevTest/config.xml", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testUpdateConfigNonExistentJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String configXML = payloadFromResource("/freestyle-project.xml"); +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.config(null, "DevTest", configXML); +// assertFalse(success); +// assertSentAccept(server, "POST", "/job/DevTest/config.xml", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testDeleteJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus success = api.delete(null, "DevTest"); +// assertNotNull(success); +// assertTrue(success.getValue()); +// assertTrue(success.errors().isEmpty()); +// assertSentAccept(server, "POST", "/job/DevTest/doDelete", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testDeleteJobNonExistent() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(400)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus success = api.delete(null, "DevTest"); +// assertNotNull(success); +// assertFalse(success.getValue()); +// assertFalse(success.errors().isEmpty()); +// assertSentAccept(server, "POST", "/job/DevTest/doDelete", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testEnableJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.enable(null, "DevTest"); +// assertTrue(success); +// assertSentAccept(server, "POST", "/job/DevTest/enable", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testEnableJobAlreadyEnabled() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.enable(null, "DevTest"); +// assertTrue(success); +// assertSentAccept(server, "POST", "/job/DevTest/enable", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testDisableJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.disable(null, "DevTest"); +// assertTrue(success); +// assertSentAccept(server, "POST", "/job/DevTest/disable", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testDisableJobAlreadyEnabled() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.disable(null, "DevTest"); +// assertTrue(success); +// assertSentAccept(server, "POST", "/job/DevTest/disable", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testBuildJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue( +// new MockResponse().setHeader("Location", "http://127.0.1.1:8080/queue/item/1/").setResponseCode(201)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// IntegerResponse output = api.build(null, "DevTest"); +// assertNotNull(output); +// assertEquals((int) output.getValue(), 1); +// assertEquals(output.errors().size(), 0); +// assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testBuildJobWithNoLocationReturned() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue( +// new MockResponse().setResponseCode(201)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// IntegerResponse output = api.build(null, "DevTest"); +// assertNotNull(output); +// assertNull(output.getValue()); +// assertEquals(output.errors().size(), 1); +// assertNull(output.errors().get(0).context()); +// assertEquals(output.errors().get(0).message(), "No queue item Location header could be found despite getting a valid HTTP response."); +// assertEquals(NumberFormatException.class.getCanonicalName(), output.errors().get(0).exceptionName()); +// assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testBuildJobNonExistentJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// IntegerResponse output = api.build(null, "DevTest"); +// assertNotNull(output); +// assertNull(output.getValue()); +// assertEquals(output.errors().size(), 1); +// assertEquals(output.errors().get(0).message(), ""); +// assertEquals(output.errors().get(0).exceptionName(), "org.jclouds.rest.ResourceNotFoundException"); +// assertNotNull(output.errors().get(0).context()); +// assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testBuildJobWithParams() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue( +// new MockResponse().setHeader("Location", "http://127.0.1.1:8080/queue/item/1/").setResponseCode(201)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// Map> params = new HashMap<>(); +// params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); +// IntegerResponse output = api.buildWithParameters(null, "DevTest", params); +// assertNotNull(output); +// assertEquals((int) output.getValue(), 1); +// assertEquals(output.errors().size(), 0); +// assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testBuildJobWithNullParamsMap() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue( +// new MockResponse().setHeader("Location", "http://127.0.1.1:8080/queue/item/1/").setResponseCode(201)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// IntegerResponse output = api.buildWithParameters(null, "DevTest", null); +// assertNotNull(output); +// assertEquals((int) output.getValue(), 1); +// assertEquals(output.errors().size(), 0); +// assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testBuildJobWithEmptyParamsMap() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue( +// new MockResponse().setHeader("Location", "http://127.0.1.1:8080/queue/item/1/").setResponseCode(201)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// IntegerResponse output = api.buildWithParameters(null, "DevTest", new HashMap<>()); +// assertNotNull(output); +// assertEquals((int) output.getValue(), 1); +// assertEquals(output.errors().size(), 0); +// assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testBuildJobWithParamsNonExistentJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// Map> params = new HashMap<>(); +// params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue")); +// IntegerResponse output = api.buildWithParameters(null, "DevTest", params); +// assertNotNull(output); +// assertNull(output.getValue()); +// assertEquals(output.errors().size(), 1); +// assertEquals(output.errors().get(0).message(), ""); +// assertEquals(output.errors().get(0).exceptionName(), "org.jclouds.rest.ResourceNotFoundException"); +// assertNotNull(output.errors().get(0).context()); +// assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetParams() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/build-info.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// List output = api.buildInfo(null, "fish", 10).actions().get(0).parameters(); +// assertNotNull(output); +// assertEquals(output.get(0).name(), "bear"); +// assertEquals(output.get(0).getValue(), "true"); +// assertEquals(output.get(1).name(), "fish"); +// assertEquals(output.get(1).getValue(), "salmon"); +// assertSent(server, "GET", "/job/fish/10/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetGitCommitInfo() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/build-info-git-commit.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// List changeSets = api.buildInfo(null, "fish", 10).changeSets().get(0).items(); +// assertNotNull(changeSets); +// assertEquals(changeSets.get(0).affectedPaths().get(0), "some/path/in/the/repository"); +// assertEquals(changeSets.get(0).commitId(), "d27afa0805201322d846d7defc29b82c88d9b5ce"); +// assertEquals(changeSets.get(0).timestamp(), 1461091892486L); +// assertEquals(changeSets.get(0).author().absoluteUrl(), "http://localhost:8080/user/username"); +// assertEquals(changeSets.get(0).author().fullName(), "username"); +// assertEquals(changeSets.get(0).authorEmail(), "username@localhost"); +// assertEquals(changeSets.get(0).comment(), "Commit comment\n"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetParamsWhenNoBuildParams() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/build-info-no-params.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// List output = api.buildInfo(null, "fish", 10).actions().get(0).parameters(); +// assertEquals(output.size(), 0); +// assertSent(server, "GET", "/job/fish/10/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetParamsWhenEmptyorNullParams() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/build-info-empty-and-null-params.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// List output = api.buildInfo(null, "fish", 10).actions().get(0).parameters(); +// assertNotNull(output); +// assertEquals(output.get(0).name(), "bear"); +// assertEquals(output.get(0).getValue(), "null"); +// assertEquals(output.get(1).name(), "fish"); +// assertTrue(output.get(1).getValue().isEmpty()); +// assertSent(server, "GET", "/job/fish/10/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetCause() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/build-info-no-params.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// List output = api.buildInfo(null, "fish", 10).actions().get(0).causes(); +// assertNotNull(output); +// assertEquals(output.get(0).shortDescription(), "Started by user anonymous"); +// assertNull(output.get(0).userId()); +// assertEquals(output.get(0).userName(), "anonymous"); +// assertSent(server, "GET", "/job/fish/10/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetLastBuildNumber() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/build-number.txt"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// Integer output = api.lastBuildNumber(null, "DevTest"); +// assertNotNull(output); +// assertEquals((int) output, 123); +// assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/buildNumber"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetLastBuildNumberJobNotExist() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// Integer output = api.lastBuildNumber(null, "DevTest"); +// assertNull(output); +// assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/buildNumber"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetLastBuildTimeStamp() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/build-timestamp.txt"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// String output = api.lastBuildTimestamp(null, "DevTest"); +// assertNotNull(output); +// assertEquals(body, output); +// assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/buildTimestamp"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetLastBuildTimeStampJobNotExist() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// String output = api.lastBuildTimestamp(null, "DevTest"); +// assertNull(output); +// assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/buildTimestamp"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetProgressiveText() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/progressive-text.txt"); +// server.enqueue(new MockResponse().setHeader("X-Text-Size", "123").setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// ProgressiveText output = api.progressiveText(null, "DevTest", 0); +// assertNotNull(output); +// assertEquals(output.size(), 123); +// assertFalse(output.hasMoreData()); +// assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/logText/progressiveText?start=0"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetProgressiveTextOfBuildNumber() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/progressive-text.txt"); +// server.enqueue(new MockResponse().setHeader("X-Text-Size", "123").setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// ProgressiveText output = api.progressiveText(null, "DevTest", 1, 0); +// assertNotNull(output); +// assertEquals(output.size(), 123); +// assertFalse(output.hasMoreData()); +// assertSentAcceptText(server, "GET", "/job/DevTest/1/logText/progressiveText?start=0"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetProgressiveTextJobNotExist() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// ProgressiveText output = api.progressiveText(null, "DevTest", 0); +// assertNull(output); +// assertSentAcceptText(server, "GET", "/job/DevTest/lastBuild/logText/progressiveText?start=0"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testRenameJob() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.rename(null, "DevTest", "NewDevTest"); +// assertTrue(success); +// assertSentAccept(server, "POST", "/job/DevTest/doRename?newName=NewDevTest", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testRenameJobNotExist() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// boolean success = api.rename(null, "DevTest", "NewDevTest"); +// assertFalse(success); +// assertSentAccept(server, "POST", "/job/DevTest/doRename?newName=NewDevTest", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testRunHistory() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/runHistory.json"); +// +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// List workflows = api.runHistory(null, "MockJob"); +// assertNotNull(workflows); +// assertSent(server, "GET", "/job/MockJob/wfapi/runs"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testRunHistoryNotExist() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// List workflows = api.runHistory(null, "MockJob"); +// assertNull(workflows); +// assertSent(server, "GET", "/job/MockJob/wfapi/runs"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testWorkflow() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/workflow.json"); +// +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// Workflow success = api.workflow(null, "DevTest", 16); +// assertNotNull(success); +// assertSent(server, "GET", "/job/DevTest/16/wfapi/describe"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testWorkflowNotExist() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// Workflow success = api.workflow(null, "DevTest", 16); +// assertNull(success); +// assertSent(server, "GET", "/job/DevTest/16/wfapi/describe"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testPipelineNode() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/pipeline-node.json"); +// +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// PipelineNode success = api.pipelineNode(null, "DevTest", 16, 17); +// assertNotNull(success); +// assertSent(server, "GET", "/job/DevTest/16/execution/node/17/wfapi/describe"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testPipelineNodeNotExist() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// PipelineNode success = api.pipelineNode(null, "DevTest", 16, 17); +// assertNull(success); +// assertSent(server, "GET", "/job/DevTest/16/execution/node/17/wfapi/describe"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testJobTestReportExists() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setHeader("Content-Type", "application/json").setBody("{ \"empty\": false }").setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// JsonObject testReport = api.testReport(null, "DevTest", 16); +// assertNotNull(testReport); +// assertFalse(testReport.get("empty").getAsBoolean()); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testJobTestReportNotExists() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// JsonObject testReport = api.testReport(null, "DevTest", 16); +// assertNull(testReport); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testPipelineNodeLog() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/pipelineNodeLog.json"); +// +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// PipelineNodeLog pipelineNodeLog = api.pipelineNodeLog(null, "MockJob", 16, 17); +// assertNotNull(pipelineNodeLog); +// assertSent(server, "GET", "/job/MockJob/16/execution/node/17/wfapi/log"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testPipelineNodeLogNotExist() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// PipelineNodeLog pipelineNodeLog = api.pipelineNodeLog(null, "MockJob", 16, 17); +// assertNull(pipelineNodeLog); +// assertSent(server, "GET", "/job/MockJob/16/execution/node/17/wfapi/log"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testStopBuild() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus status = api.stop(null, "fish", 99); +// assertNotNull(status); +// assertTrue(status.getValue()); +// assertTrue(status.errors().isEmpty()); +// assertSent(server, "POST", "/job/fish/99/stop"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testTermBuild() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus status = api.term(null, "fish", 99); +// assertNotNull(status); +// assertTrue(status.getValue()); +// assertTrue(status.errors().isEmpty()); +// assertSent(server, "POST", "/job/fish/99/term"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testKillBuild() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus status = api.kill(null, "fish", 99); +// assertNotNull(status); +// assertTrue(status.getValue()); +// assertTrue(status.errors().isEmpty()); +// assertSent(server, "POST", "/job/fish/99/kill"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testTermBuildReturns404() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse() +// .setHeader("Location", server.url("/").url() + "job/fish/99/term/") +// .setResponseCode(302)); +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus status = api.term(null, "fish", 99); +// assertSent(server, "POST", "/job/fish/99/term"); +// assertNotNull(status); +// assertFalse(status.getValue()); +// assertFalse(status.errors().isEmpty()); +// assertEquals(status.errors().size(), 1); +// System.out.println("Mock Status: " + status); +// assertEquals(status.errors().get(0).message(), "The term operation does not exist for " + +// server.url("/").url() + +// "job/fish/99/term/, try stop instead."); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testKillBuildReturns404() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse() +// .setHeader("Location", server.url("/").url() + "job/fish/99/kill/") +// .setResponseCode(302)); +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// JobsApi api = jenkinsApi.jobsApi(); +// try { +// RequestStatus status = api.kill(null, "fish", 99); +// assertSent(server, "POST", "/job/fish/99/kill"); +// assertNotNull(status); +// assertFalse(status.getValue()); +// assertFalse(status.errors().isEmpty()); +// assertEquals(status.errors().size(), 1); +// assertEquals(status.errors().get(0).message(), "The kill operation does not exist for " + +// server.url("/").url() + +// "job/fish/99/kill/, try stop instead."); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/PluginManagerApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/PluginManagerApiLiveTest.java new file mode 100644 index 0000000..adb9bd8 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/PluginManagerApiLiveTest.java @@ -0,0 +1,49 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.plugins.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +//@Test(groups = "live", testName = "PluginManagerApiLiveTest", singleThreaded = true) +//public class PluginManagerApiLiveTest extends BaseJenkinsApiLiveTest { +// +// @Test +// public void testGetPlugins() { +// final Plugins plugins = api().plugins(3, null); +// assertNotNull(plugins); +// assertTrue(plugins.errors().isEmpty()); +// assertFalse(plugins.plugins().isEmpty()); +// assertNotNull(plugins.plugins().get(0).shortName()); +// } +// +// @Test +// public void testInstallNecessaryPlugins() { +// final RequestStatus status = api().installNecessaryPlugins("artifactory@2.2.1"); +// assertNotNull(status); +// assertTrue(status.getValue()); +// assertTrue(status.errors().isEmpty()); +// } +// +// private PluginManagerApi api() { +// return api.pluginManagerApi(); +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/PluginManagerApiMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/PluginManagerApiMockTest.java new file mode 100644 index 0000000..42318e2 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/PluginManagerApiMockTest.java @@ -0,0 +1,97 @@ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.plugins.*; +//import okhttp3.mockwebserver.*; +//import org.testng.annotations.*; +// +//import java.util.*; +// +//import static org.testng.Assert.*; +// +///** +// * Mock tests for the {@link PluginManagerApi} class. +// */ +//@Test(groups = "unit", testName = "PluginManagerApiMockTest") +//public class PluginManagerApiMockTest extends BaseJenkinsMockTest { +// +// public void testGetPlugins() throws Exception { +// final MockWebServer server = mockWebServer(); +// server.enqueue(new MockResponse().setBody(payloadFromResource("/plugins.json")).setResponseCode(200)); +// +// final JenkinsApi jenkinsApi = api(server.url("/").url()); +// final PluginManagerApi api = jenkinsApi.pluginManagerApi(); +// try { +// final Plugins plugins = api.plugins(3, null); +// assertNotNull(plugins); +// assertTrue(plugins.errors().isEmpty()); +// assertFalse(plugins.plugins().isEmpty()); +// assertNotNull(plugins.plugins().get(0).shortName()); +// final Map queryParams = Maps.newHashMap(); +// queryParams.put("depth", 3); +// assertSent(server, "GET", "/pluginManager/api/json", queryParams); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetPluginsOnAuthException() throws Exception { +// final MockWebServer server = mockWebServer(); +// server.enqueue(new MockResponse().setResponseCode(401)); +// +// final JenkinsApi jenkinsApi = api(server.url("/").url()); +// final PluginManagerApi api = jenkinsApi.pluginManagerApi(); +// try { +// final Plugins plugins = api.plugins(3, null); +// assertNotNull(plugins); +// assertNull(plugins.clazz()); +// assertFalse(plugins.errors().isEmpty()); +// assertTrue(plugins.errors().get(0).exceptionName().endsWith("AuthorizationException")); +// final Map queryParams = Maps.newHashMap(); +// queryParams.put("depth", 3); +// assertSent(server, "GET", "/pluginManager/api/json", queryParams); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testInstallNecessaryPlugins() throws Exception { +// final MockWebServer server = mockWebServer(); +// server.enqueue(new MockResponse().setResponseCode(200)); +// +// final JenkinsApi jenkinsApi = api(server.url("/").url()); +// final PluginManagerApi api = jenkinsApi.pluginManagerApi(); +// try { +// final RequestStatus status = api.installNecessaryPlugins("artifactory@2.2.1"); +// assertNotNull(status); +// assertTrue(status.getValue()); +// assertTrue(status.errors().isEmpty()); +// assertSent(server, "POST", "/pluginManager/installNecessaryPlugins"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testInstallNecessaryPluginsOnAuthException() throws Exception { +// final MockWebServer server = mockWebServer(); +// server.enqueue(new MockResponse().setResponseCode(401)); +// +// final JenkinsApi jenkinsApi = api(server.url("/").url()); +// final PluginManagerApi api = jenkinsApi.pluginManagerApi(); +// try { +// final RequestStatus status = api.installNecessaryPlugins("artifactory@2.2.1"); +// assertNotNull(status); +// assertFalse(status.getValue()); +// assertFalse(status.errors().isEmpty()); +// assertTrue(status.errors().get(0).exceptionName().endsWith("AuthorizationException")); +// assertSent(server, "POST", "/pluginManager/installNecessaryPlugins"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/QueueApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/QueueApiLiveTest.java new file mode 100644 index 0000000..04de16b --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/QueueApiLiveTest.java @@ -0,0 +1,228 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.queue.*; +//import org.testng.annotations.*; +// +//import java.util.*; +// +//import static org.testng.Assert.*; +// +//@Test(groups = "live", testName = "QueueApiLiveTest", singleThreaded = true) +//public class QueueApiLiveTest extends BaseJenkinsApiLiveTest { +// +// @BeforeClass +// public void init() { +// String config = payloadFromResource("/freestyle-project-sleep-task.xml"); +// RequestStatus success = api.jobsApi().create(null, "QueueTest", config); +// assertTrue(success.getValue()); +// +// config = payloadFromResource("/freestyle-project.xml"); +// success = api.jobsApi().create(null, "QueueTestSingleParam", config); +// assertTrue(success.getValue()); +// +// config = payloadFromResource("/freestyle-project-sleep-task-multiple-params.xml"); +// success = api.jobsApi().create(null, "QueueTestMultipleParams", config); +// assertTrue(success.getValue()); +// } +// +// @Test +// public void testGetQueue() { +// IntegerResponse job1 = api.jobsApi().build(null, "QueueTest"); +// assertNotNull(job1); +// assertEquals(job1.errors().size(), 0); +// IntegerResponse job2 = api.jobsApi().build(null, "QueueTest"); +// assertNotNull(job2); +// assertEquals(job2.errors().size(), 0); +// List queueItems = api().queue(); +// assertTrue(queueItems.size() > 0); +// boolean foundLastKickedJob = false; +// for (QueueItem item : queueItems) { +// if (item.id() == job2.getValue()) { +// foundLastKickedJob = true; +// break; +// } +// } +// assertTrue(foundLastKickedJob); +// } +// +// @Test +// public void testGetPendingQueueItem() { +// IntegerResponse job1 = api.jobsApi().build(null, "QueueTest"); +// assertNotNull(job1); +// assertEquals(job1.errors().size(), 0); +// IntegerResponse job2 = api.jobsApi().build(null, "QueueTest"); +// assertNotNull(job2); +// assertEquals(job2.errors().size(), 0); +// +// // job2 is queue after job1, so while job1 runs, job2 is pending in the queue +// QueueItem queueItem = api().queueItem(job2.getValue()); +// assertFalse(queueItem.cancelled()); +// assertNotNull(queueItem.why()); +// assertNull(queueItem.executable()); +// } +// +// @Test +// public void testGetRunningQueueItem() throws InterruptedException { +// IntegerResponse job1 = api.jobsApi().build(null, "QueueTest"); +// assertNotNull(job1); +// assertEquals(job1.errors().size(), 0); +// IntegerResponse job2 = api.jobsApi().build(null, "QueueTest"); +// assertNotNull(job2); +// assertEquals(job2.errors().size(), 0); +// +// // job1 runs first, so we get its queueItem +// QueueItem queueItem = getRunningQueueItem(job1.getValue()); +// +// // If null, it means the queueItem has been cancelled, which would not be normal in this test +// assertNotNull(queueItem); +// assertFalse(queueItem.cancelled()); +// +// // We exepect this build to run, consequently: +// // * the why field should now be null +// // * the executable field should NOT be null +// // * the build number should be set to an integer +// // * the url for the build should be set to a string +// assertNull(queueItem.why()); +// assertNotNull(queueItem.executable()); +// } +// +// @Test +// public void testQueueItemSingleParameters() throws InterruptedException { +// Map> params = new HashMap<>(); +// params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue1")); +// IntegerResponse job1 = api.jobsApi().buildWithParameters(null, "QueueTestSingleParam", params); +// assertNotNull(job1); +// assertTrue(job1.getValue() > 0); +// assertEquals(job1.errors().size(), 0); +// +// // Jenkins will reject two consecutive build requests when the build parameter values are the same +// // So we must set some different parameter values +// params = new HashMap<>(); +// params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue2")); +// IntegerResponse job2 = api.jobsApi().buildWithParameters(null, "QueueTestSingleParam", params); +// assertNotNull(job2); +// assertTrue(job2.getValue() > 0); +// assertEquals(job2.errors().size(), 0); +// +// QueueItem queueItem = getRunningQueueItem(job1.getValue()); +// assertNotNull(queueItem); +// assertFalse(queueItem.cancelled()); +// +// Map map = Maps.newHashMap(); +// map.put("SomeKey", "SomeVeryNewValue1"); +// assertEquals(queueItem.params(), map); +// } +// +// @Test +// public void testQueueItemMultipleParameters() throws InterruptedException { +// Map> params = new HashMap<>(); +// params.put("SomeKey1", Lists.newArrayList("SomeVeryNewValue1")); +// IntegerResponse job1 = api.jobsApi().buildWithParameters(null, "QueueTestMultipleParams", params); +// assertNotNull(job1); +// assertTrue(job1.getValue() > 0); +// assertEquals(job1.errors().size(), 0); +// +// // Jenkins will reject two consecutive build requests when the build parameter values are the same +// // So we must set some different parameter values +// params = new HashMap<>(); +// params.put("SomeKey1", Lists.newArrayList("SomeVeryNewValue2")); +// IntegerResponse job2 = api.jobsApi().buildWithParameters(null, "QueueTestMultipleParams", params); +// assertNotNull(job2); +// assertTrue(job2.getValue() > 0); +// assertEquals(job2.errors().size(), 0); +// +// QueueItem queueItem = getRunningQueueItem(job1.getValue()); +// assertNotNull(queueItem); +// assertFalse(queueItem.cancelled()); +// +// Map map = Maps.newHashMap(); +// map.put("SomeKey1", "SomeVeryNewValue1"); +// map.put("SomeKey2", "SomeValue2"); +// map.put("SomeKey3", "SomeValue3"); +// assertEquals(queueItem.params(), map); +// } +// +// @Test +// public void testQueueItemEmptyParameterValue() throws InterruptedException { +// Map> params = new HashMap<>(); +// params.put("SomeKey1", Lists.newArrayList("")); +// IntegerResponse job1 = api.jobsApi().buildWithParameters(null, "QueueTestMultipleParams", params); +// assertNotNull(job1); +// assertTrue(job1.getValue() > 0); +// assertEquals(job1.errors().size(), 0); +// +// QueueItem queueItem = getRunningQueueItem(job1.getValue()); +// assertNotNull(queueItem); +// +// Map map = Maps.newHashMap(); +// map.put("SomeKey1", ""); +// map.put("SomeKey2", "SomeValue2"); +// map.put("SomeKey3", "SomeValue3"); +// assertEquals(queueItem.params(), map); +// } +// +// @Test +// public void testGetCancelledQueueItem() { +// IntegerResponse job1 = api.jobsApi().build(null, "QueueTest"); +// assertNotNull(job1); +// assertEquals(job1.errors().size(), 0); +// IntegerResponse job2 = api.jobsApi().build(null, "QueueTest"); +// assertNotNull(job2); +// assertEquals(job2.errors().size(), 0); +// +// RequestStatus success = api().cancel(job2.getValue()); +// assertNotNull(success); +// assertTrue(success.getValue()); +// assertTrue(success.errors().isEmpty()); +// +// QueueItem queueItem = api().queueItem(job2.getValue()); +// assertTrue(queueItem.cancelled()); +// assertNull(queueItem.why()); +// assertNull(queueItem.executable()); +// } +// +// @Test +// public void testCancelNonExistentQueueItem() { +// RequestStatus success = api().cancel(123456789); +// assertNotNull(success); +// assertTrue(success.getValue()); +// assertTrue(success.errors().isEmpty()); +// } +// +// @AfterClass +// public void finish() { +// RequestStatus success = api.jobsApi().delete(null, "QueueTest"); +// assertNotNull(success); +// assertTrue(success.getValue()); +// +// success = api.jobsApi().delete(null, "QueueTestSingleParam"); +// assertNotNull(success); +// assertTrue(success.getValue()); +// +// success = api.jobsApi().delete(null, "QueueTestMultipleParams"); +// assertNotNull(success); +// assertTrue(success.getValue()); +// } +// +// private QueueApi api() { +// return api.queueApi(); +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/QueueApiMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/QueueApiMockTest.java new file mode 100644 index 0000000..8e9334c --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/QueueApiMockTest.java @@ -0,0 +1,220 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.queue.*; +//import okhttp3.mockwebserver.*; +//import org.testng.annotations.*; +// +//import java.util.*; +// +//import static org.testng.Assert.*; +// +///** +// * Mock tests for the {@link QueueApi} class. +// */ +//@Test(groups = "unit", testName = "QueueApiMockTest") +//public class QueueApiMockTest extends BaseJenkinsMockTest { +// +// public void testGetQueue() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/queue.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// QueueApi api = jenkinsApi.queueApi(); +// try { +// List output = api.queue(); +// assertEquals(output.size(), 2); +// assertSent(server, "GET", "/queue/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetPendingQueueItem() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/queueItemPending.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); +// try { +// assertFalse(queueItem.cancelled()); +// assertEquals(queueItem.why(), "Build #9 is already in progress (ETA:15 sec)"); +// assertNull(queueItem.executable()); +// assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetCancelledQueueItem() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/queueItemCancelled.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); +// try { +// assertTrue(queueItem.cancelled()); +// assertNull(queueItem.why()); +// assertNull(queueItem.executable()); +// assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetRunningQueueItem() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/queueItemRunning.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// int buildNumber = 14; +// QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); +// Map map = Maps.newHashMap(); +// map.put("a", "4"); +// try { +// assertEquals(queueItem.params(), map); +// assertFalse(queueItem.cancelled()); +// assertNull(queueItem.why()); +// assertNotNull(queueItem.executable()); +// assertEquals((int) queueItem.executable().number(), buildNumber); +// assertEquals(queueItem.executable().url(), "http://localhost:8082/job/test/" + buildNumber + "/"); +// assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testQueueItemMultipleParameters() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/queueItemMultipleParameters.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); +// Map map = Maps.newHashMap(); +// map.put("a", "1"); +// map.put("b", "2"); +// map.put("c", "3"); +// try { +// assertEquals(queueItem.params(), map); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testQueueItemEmptyParameterValue() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/queueItemEmptyParameterValue.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); +// Map map = Maps.newHashMap(); +// map.put("a", "1"); +// map.put("b", ""); +// map.put("c", "3"); +// try { +// assertEquals(queueItem.params(), map); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testCancelQueueItem() throws Exception { +// MockWebServer server = mockWebServer(); +// server.enqueue(new MockResponse().setResponseCode(404)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// RequestStatus result = jenkinsApi.queueApi().cancel(queueItemId); +// try { +// assertNotNull(result); +// assertTrue(result.getValue()); +// assertTrue(result.errors().isEmpty()); +// assertSentWithFormData(server, "POST", "/queue/cancelItem", "id=" + queueItemId); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testCancelNonExistentQueueItem() throws Exception { +// MockWebServer server = mockWebServer(); +// server.enqueue(new MockResponse().setResponseCode(500)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// RequestStatus result = jenkinsApi.queueApi().cancel(queueItemId); +// try { +// assertNotNull(result); +// assertFalse(result.getValue()); +// assertFalse(result.errors().isEmpty()); +// assertSentWithFormData(server, "POST", "/queue/cancelItem", "id=" + queueItemId); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testQueueItemNullTaskName() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/queueItemNullTaskName.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); +// try { +// assertFalse(queueItem.cancelled()); +// assertEquals(queueItem.why(), "Build #9 is already in progress (ETA:15 sec)"); +// assertNull(queueItem.executable()); +// assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testQueueItemMissingTaskUrl() throws Exception { +// MockWebServer server = mockWebServer(); +// String body = payloadFromResource("/queueItemMissingTaskUrl.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// int queueItemId = 143; +// QueueItem queueItem = jenkinsApi.queueApi().queueItem(queueItemId); +// try { +// assertFalse(queueItem.cancelled()); +// assertEquals(queueItem.why(), "Just a random message here"); +// assertNull(queueItem.executable()); +// assertSent(server, "GET", "/queue/item/" + queueItemId + "/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/StatisticsApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/StatisticsApiLiveTest.java new file mode 100644 index 0000000..f20f22e --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/StatisticsApiLiveTest.java @@ -0,0 +1,36 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.statistics.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +//@Test(groups = "live", testName = "StatisticsApiLiveTest", singleThreaded = true) +//public class StatisticsApiLiveTest extends BaseJenkinsApiLiveTest { +// @Test +// public void testOverallLoad() { +// OverallLoad load = api().overallLoad(); +// assertNotNull(load); +// } +// +// private StatisticsApi api() { +// return api.statisticsApi(); +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/StatisticsApiMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/StatisticsApiMockTest.java new file mode 100644 index 0000000..4252547 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/StatisticsApiMockTest.java @@ -0,0 +1,48 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.statistics.*; +//import okhttp3.mockwebserver.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +///** +// * Mock tests for the {@link StatisticsApi} +// * class. +// */ +//@Test(groups = "unit", testName = "StatisticsApiMockTest") +//public class StatisticsApiMockTest extends BaseJenkinsMockTest { +// +// public void testOverallLoad() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setBody(payloadFromResource("/overall-load.json")).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// StatisticsApi api = jenkinsApi.statisticsApi(); +// try { +// OverallLoad load = api.overallLoad(); +// assertNotNull(load); +// assertSent(server, "GET", "/overallLoad/api/json"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +//} diff --git a/src/test/java/com/cdancy/jenkins/rest/features/SystemApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/SystemApiLiveTest.java similarity index 77% rename from src/test/java/com/cdancy/jenkins/rest/features/SystemApiLiveTest.java rename to src/test/java/io/github/hmedioni/jenkins/client/features/SystemApiLiveTest.java index c753d63..15e51b3 100644 --- a/src/test/java/com/cdancy/jenkins/rest/features/SystemApiLiveTest.java +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/SystemApiLiveTest.java @@ -14,16 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.cdancy.jenkins.rest.features; +package io.github.hmedioni.jenkins.client.features; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; +import io.github.hmedioni.jenkins.client.*; +import io.github.hmedioni.jenkins.client.domain.common.*; +import io.github.hmedioni.jenkins.client.domain.system.*; +import org.testng.annotations.*; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import org.testng.annotations.Test; - -import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest; -import com.cdancy.jenkins.rest.domain.system.SystemInfo; +import static org.testng.Assert.*; @Test(groups = "live", testName = "SystemApiLiveTest", singleThreaded = true) public class SystemApiLiveTest extends BaseJenkinsApiLiveTest { @@ -32,35 +30,35 @@ public class SystemApiLiveTest extends BaseJenkinsApiLiveTest { public void testGetSystemInfo() { final SystemInfo version = api().systemInfo(); assertNotNull(version); - assertNotNull(version.jenkinsVersion()); + assertNotNull(version.getJenkinsVersion()); } @Test public void testQuietDown() { RequestStatus success = api().quietDown(); assertNotNull(success); - assertTrue(success.value()); + assertTrue(success.getValue()); } @Test(dependsOnMethods = "testQuietDown") public void testAlreadyQuietDown() { RequestStatus success = api().quietDown(); assertNotNull(success); - assertTrue(success.value()); + assertTrue(success.getValue()); } @Test(dependsOnMethods = "testAlreadyQuietDown") public void testCancelQuietDown() { RequestStatus success = api().cancelQuietDown(); assertNotNull(success); - assertTrue(success.value()); + assertTrue(success.getValue()); } @Test(dependsOnMethods = "testCancelQuietDown") public void testAlreadyCanceledQuietDown() { RequestStatus success = api().cancelQuietDown(); assertNotNull(success); - assertTrue(success.value()); + assertTrue(success.getValue()); } private SystemApi api() { diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/SystemApiMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/SystemApiMockTest.java new file mode 100644 index 0000000..3dee162 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/SystemApiMockTest.java @@ -0,0 +1,145 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.system.*; +//import okhttp3.mockwebserver.*; +//import org.springframework.http.*; +//import org.testng.annotations.*; +// +// +// +//import static org.testng.Assert.*; +// +///** +// * Mock tests for the {@link SystemApi} class. +// */ +//@Test(groups = "unit", testName = "SystemApiMockTest") +//public class SystemApiMockTest extends BaseJenkinsMockTest { +// +// public void testGetSystemInfo() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue( +// new MockResponse().setHeader("X-Hudson", "1.395").setHeader("X-Jenkins", JenkinsApiMetadata.BUILD_VERSION) +// .setHeader("X-Jenkins-Session", "cc323b8d").setHeader("X-Hudson-CLI-Port", "50000") +// .setHeader("X-Jenkins-CLI-Port", "50000").setHeader("X-Jenkins-CLI2-Port", "50000") +// .setHeader("X-Instance-Identity", "fdsa").setHeader("X-SSH-Endpoint", "127.0.1.1:46126") +// .setHeader("Server", "Jetty(winstone-2.9)").setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// SystemApi api = jenkinsApi.systemApi(); +// try { +// final SystemInfo version = api.systemInfo(); +// assertNotNull(version); +// assertTrue(version.jenkinsVersion().equalsIgnoreCase(JenkinsApiMetadata.BUILD_VERSION)); +// assertSent(server, "HEAD", "/"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testGetSystemInfoOnError() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue( +// new MockResponse().setBody("Not Authorized").setResponseCode(401)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// SystemApi api = jenkinsApi.systemApi(); +// try { +// final SystemInfo version = api.systemInfo(); +// assertNotNull(version); +// assertFalse(version.errors().isEmpty()); +// assertSent(server, "HEAD", "/"); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testQuietDown() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// SystemApi api = jenkinsApi.systemApi(); +// try { +// RequestStatus success = api.quietDown(); +// assertNotNull(success); +// assertTrue(success.getValue()); +// assertSentAccept(server, "POST", "/quietDown", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testQuietDownOnAuthException() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(401)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// SystemApi api = jenkinsApi.systemApi(); +// try { +// RequestStatus status = api.quietDown(); +// assertFalse(status.getValue()); +// assertFalse(status.errors().isEmpty()); +// assertTrue(status.errors().get(0).exceptionName().endsWith("AuthorizationException")); +// assertSentAccept(server, "POST", "/quietDown", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testCancelQuietDown() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// SystemApi api = jenkinsApi.systemApi(); +// try { +// RequestStatus success = api.cancelQuietDown(); +// assertNotNull(success); +// assertTrue(success.getValue()); +// assertSentAccept(server, "POST", "/cancelQuietDown", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// public void testCancelQuietDownOnAuthException() throws Exception { +// MockWebServer server = mockWebServer(); +// +// server.enqueue(new MockResponse().setResponseCode(401)); +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// SystemApi api = jenkinsApi.systemApi(); +// try { +// RequestStatus status = api.cancelQuietDown(); +// assertFalse(status.getValue()); +// assertFalse(status.errors().isEmpty()); +// assertTrue(status.errors().get(0).exceptionName().endsWith("AuthorizationException")); +// assertSentAccept(server, "POST", "/cancelQuietDown", MediaType.TEXT_HTML); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/UserApiLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/UserApiLiveTest.java new file mode 100644 index 0000000..cfd8311 --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/UserApiLiveTest.java @@ -0,0 +1,74 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.common.*; +//import io.github.hmedioni.jenkins.client.domain.user.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +//@Test(groups = "live", testName = "UserApiLiveTest", singleThreaded = true) +//public class UserApiLiveTest extends BaseJenkinsApiLiveTest { +// +// ApiToken token; +// +// @Test +// public void testGetUser() { +// User user = api().get(); +// assertNotNull(user); +// assertNotNull(user.absoluteUrl()); +// assertEquals(user.absoluteUrl(), System.getProperty("test.jenkins.endpoint") + "/user/admin"); +// assertTrue(user.description() == null || user.description().equals("")); +// assertNotNull(user.fullName()); +// assertEquals(user.fullName(), "admin"); +// assertNotNull(user.id()); +// assertEquals(user.id(), "admin"); +// } +// +// @Test +// public void testGenerateNewToken() { +// token = api().generateNewToken("user-api-test-token"); +// assertNotNull(token); +// assertEquals(token.status(), "ok"); +// assertNotNull(token.data()); +// assertNotNull(token.data().tokenName()); +// assertEquals(token.data().tokenName(), "user-api-test-token"); +// assertNotNull(token.data().tokenUuid()); +// assertNotNull(token.data().tokenValue()); +// } +// +// @Test(dependsOnMethods = "testGenerateNewToken") +// public void testRevokeApiToken() { +// RequestStatus status = api().revoke(token.data().tokenUuid()); +// // Jenkins returns 200 whether the tokenUuid is correct or not. +// assertTrue(status.getValue()); +// } +// +// @Test +// public void testRevokeApiTokenWithEmptyUuid() { +// RequestStatus status = api().revoke(""); +// assertFalse(status.getValue()); +// // TODO: Deal with the HTML response from Jenkins Stapler +// } +// +// private UserApi api() { +// return api.userApi(); +// } +//} diff --git a/src/test/java/io/github/hmedioni/jenkins/client/features/UserApiMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/features/UserApiMockTest.java new file mode 100644 index 0000000..5d110bb --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/features/UserApiMockTest.java @@ -0,0 +1,83 @@ +///* +// * 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. +// */ +//package io.github.hmedioni.jenkins.client.features; +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.domain.user.*; +//import okhttp3.mockwebserver.*; +//import org.testng.annotations.*; +// +//import static org.testng.Assert.*; +// +///** +// * Mock tests for the {@link JobsApi} class. +// */ +//@Test(groups = "unit", testName = "UserApiMockTest") +//public class UserApiMockTest extends BaseJenkinsMockTest { +// +// @Test +// public void testGetUser() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/user.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// //JenkinsApi jenkinsApi = api(server.url("/").url()); +// try (JenkinsApi jenkinsApi = api(server.url("/").url())) { +// UserApi api = jenkinsApi.userApi(); +// User output = api.get(); +// assertNotNull(output); +// assertNotNull(output.absoluteUrl()); +// assertEquals(output.absoluteUrl(), "http://localhost:8080/user/admin"); +// assertNull(output.description()); +// assertNotNull(output.fullName()); +// assertEquals(output.fullName(), "Administrator"); +// assertNotNull(output.id()); +// assertEquals(output.id(), "admin"); +// assertSent(server, "GET", "/user/user/api/json"); +// } finally { +// server.shutdown(); +// } +// } +// +// @Test +// public void testGenerateNewApiToken() throws Exception { +// MockWebServer server = mockWebServer(); +// +// String body = payloadFromResource("/api-token.json"); +// server.enqueue(new MockResponse().setBody(body).setResponseCode(200)); +// try (JenkinsApi jenkinsApi = api(server.url("/").url())) { +// UserApi api = jenkinsApi.userApi(); +// ApiToken output = api.generateNewToken("random"); +// assertNotNull(output); +// assertNotNull(output.status()); +// assertEquals(output.status(), "ok"); +// assertNotNull(output.data()); +// assertNotNull(output.data().tokenName()); +// assertEquals(output.data().tokenName(), "kb-token"); +// assertNotNull(output.data().tokenUuid()); +// assertEquals(output.data().tokenUuid(), "8c42630b-4be5-4f51-b4e9-f17a8ac07521"); +// assertNotNull(output.data().tokenValue()); +// assertEquals(output.data().tokenValue(), "112fe6e9b1b94eb1ee58f0ea4f5a1ac7bf"); +// assertSentWithFormData(server, "POST", "/user/user/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken", "newTokenName=random"); +// } finally { +// server.shutdown(); +// } +// } +// +// // TODO: testRevokeApiToken +// // TODO: testRevokeApiTokenWithEmptyUuid +//} diff --git a/src/test/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilterLiveTest.java b/src/test/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilterLiveTest.java similarity index 79% rename from src/test/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilterLiveTest.java rename to src/test/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilterLiveTest.java index 6b5bb65..eb320a9 100644 --- a/src/test/java/com/cdancy/jenkins/rest/filters/JenkinsAuthenticationFilterLiveTest.java +++ b/src/test/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilterLiveTest.java @@ -14,20 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.cdancy.jenkins.rest.filters; +package io.github.hmedioni.jenkins.client.filters; -import com.cdancy.jenkins.rest.BaseJenkinsTest; -import com.cdancy.jenkins.rest.JenkinsApi; -import com.cdancy.jenkins.rest.auth.AuthenticationType; -import com.cdancy.jenkins.rest.domain.common.RequestStatus; -import com.cdancy.jenkins.rest.domain.user.ApiToken; -import com.cdancy.jenkins.rest.features.UserApi; +import io.github.hmedioni.jenkins.client.*; +import io.github.hmedioni.jenkins.client.auth.*; +import io.github.hmedioni.jenkins.client.domain.common.*; +import io.github.hmedioni.jenkins.client.domain.user.*; +import io.github.hmedioni.jenkins.client.features.*; +import org.testng.annotations.*; -import java.net.URL; +import java.net.*; -import org.testng.annotations.Test; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.*; @Test(groups = "live", testName = "FilterApiLiveTest", singleThreaded = true) public class JenkinsAuthenticationFilterLiveTest extends BaseJenkinsTest { @@ -35,16 +33,16 @@ public class JenkinsAuthenticationFilterLiveTest extends BaseJenkinsTest { @Test public void testAnonymousNeedsCrumb() throws Exception { - try (JenkinsApi jenkinsApi = api(new URL(endPoint), AuthenticationType.Anonymous, null)) { + try (JenkinsApi jenkinsApi = api(new URL(endPoint), AuthenticationType.ANONYMOUS, null)) { // Do something that needs POST so the crumb logic is exercized String config = payloadFromResource("/freestyle-project-no-params.xml"); RequestStatus success = jenkinsApi.jobsApi().create(null, "DevTest", config); - assertTrue(success.value()); + assertTrue(success.getValue()); // Delete the job RequestStatus success2 = jenkinsApi.jobsApi().delete(null, "DevTest"); assertNotNull(success2); - assertTrue(success2.value()); + assertTrue(success2.getValue()); // Debugging note: Jenkins returns 302 after POSTing the delete, causing JClouds to follow the redirect and POST again } } @@ -53,16 +51,16 @@ public void testAnonymousNeedsCrumb() throws Exception { public void testUsernamePasswordNeedsCrumb() throws Exception { final String usernamePassword = System.getProperty("test.jenkins.usernamePassword"); - try (JenkinsApi jenkinsApi = api(new URL(endPoint), AuthenticationType.UsernamePassword, usernamePassword)) { + try (JenkinsApi jenkinsApi = api(new URL(endPoint), AuthenticationType.USERNAME_PASSWORD, usernamePassword)) { // Do something that needs POST so the crumb logic is exercized String config = payloadFromResource("/freestyle-project-no-params.xml"); RequestStatus success = jenkinsApi.jobsApi().create(null, "DevTest", config); - assertTrue(success.value()); + assertTrue(success.getValue()); // Delete the job RequestStatus success2 = jenkinsApi.jobsApi().delete(null, "DevTest"); assertNotNull(success2); - assertTrue(success2.value()); + assertTrue(success2.getValue()); // Debugging note: Jenkins returns 302 after POSTing the delete, causing JClouds to follow the redirect and POST again } } @@ -74,19 +72,19 @@ public void testUsernameApiTokenNeedsNoCrumb() throws Exception { final ApiToken apiToken = generateNewApiToken(usernamePassword); // Create a Jenkins Client using the API Token - System.out.println("Okay, we have the token: " + apiToken.data().tokenValue()); - final String usernameApiToken = usernamePassword.split(":")[0] + ":" + apiToken.data().tokenValue(); + System.out.println("Okay, we have the token: " + apiToken.getData().getTokenValue()); + final String usernameApiToken = usernamePassword.split(":")[0] + ":" + apiToken.getData().getTokenValue(); - try (JenkinsApi jenkinsApi = api(new URL(endPoint), AuthenticationType.UsernameApiToken, usernameApiToken)) { + try (JenkinsApi jenkinsApi = api(new URL(endPoint), AuthenticationType.USERNAME_API_TOKEN, usernameApiToken)) { // Do something that needs POST so the crumb logic is exercized String config = payloadFromResource("/freestyle-project-no-params.xml"); RequestStatus success = jenkinsApi.jobsApi().create(null, "DevTest", config); - assertTrue(success.value()); + assertTrue(success.getValue()); // Delete the job RequestStatus success2 = jenkinsApi.jobsApi().delete(null, "DevTest"); assertNotNull(success2); - assertTrue(success2.value()); + assertTrue(success2.getValue()); // Debugging note: Jenkins returns 302 after POSTing the delete, causing JClouds to follow the redirect and POST again } finally { revokeApiToken(usernameApiToken, apiToken); @@ -95,7 +93,7 @@ public void testUsernameApiTokenNeedsNoCrumb() throws Exception { private ApiToken generateNewApiToken(final String credStr) throws Exception { UserApi user; - try (JenkinsApi api = api(new URL(endPoint), AuthenticationType.UsernamePassword, credStr)) { + try (JenkinsApi api = api(new URL(endPoint), AuthenticationType.USERNAME_PASSWORD, credStr)) { user = api.userApi(); } return user.generateNewToken("filter-test-token"); @@ -103,10 +101,10 @@ private ApiToken generateNewApiToken(final String credStr) throws Exception { private void revokeApiToken(final String credStr, final ApiToken apiToken) throws Exception { UserApi user; - try (JenkinsApi api = api(new URL(endPoint), AuthenticationType.UsernameApiToken, credStr)) { + try (JenkinsApi api = api(new URL(endPoint), AuthenticationType.USERNAME_API_TOKEN, credStr)) { user = api.userApi(); } - user.revoke(apiToken.data().tokenUuid()); + user.revoke(apiToken.getData().getTokenUuid()); } } diff --git a/src/test/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilterMockTest.java b/src/test/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilterMockTest.java new file mode 100644 index 0000000..841730e --- /dev/null +++ b/src/test/java/io/github/hmedioni/jenkins/client/filters/JenkinsAuthenticationFilterMockTest.java @@ -0,0 +1,126 @@ +///* +// * 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. +// */ +// +//package io.github.hmedioni.jenkins.client.filters; +// +// +//import io.github.hmedioni.jenkins.client.*; +//import io.github.hmedioni.jenkins.client.auth.*; +//import okhttp3.mockwebserver.*; +//import org.springframework.http.*; +//import org.testng.annotations.*; +// +// +// +//import static org.testng.Assert.*; +// +//public class JenkinsAuthenticationFilterMockTest extends BaseJenkinsMockTest { +// +// @Test +// public void testAnonymousNeedsCrumb() throws Exception { +// MockWebServer server = mockWebServer(); +// +// final String value = "04a1109fc2db171362c966ebe9fc87f0"; +// server.enqueue(new MockResponse().setBody("Jenkins-Crumb:" + value).setResponseCode(200)); +// JenkinsApi jenkinsApi = anonymousAuthApi(server.url("/").url()); +// +// JenkinsAuthentication creds = creds(AuthenticationType.Anonymous, null); +// JenkinsAuthenticationFilter filter = new JenkinsAuthenticationFilter(creds, jenkinsApi); +// HttpRequest httpRequest = HttpRequest.builder().endpoint(server.url("/").url().toString()).method("POST").build(); +// try { +// httpRequest = filter.filter(httpRequest); +// assertEquals(httpRequest.getEndpoint().toString(), server.url("/").url().toString()); +// assertSentAccept(server, "GET", "/crumbIssuer/api/xml?xpath=concat%28//crumbRequestField,%22%3A%22,//crumb%29", MediaType.TEXT_PLAIN); +// Multimap headers = httpRequest.getHeaders(); +// assertEquals(headers.size(), 2); +// assertTrue(headers.containsEntry("Jenkins-Crumb", value)); +// assertTrue(headers.containsEntry("Cookie", "")); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// @Test +// public void testUsernamePasswordNeedsCrumb() throws Exception { +// MockWebServer server = mockWebServer(); +// +// final String value = "04a1109fc2db171362c966ebe9fc87f0"; +// final String usernamePassword = "random_user:random_password"; +// server.enqueue(new MockResponse().setBody("Jenkins-Crumb:" + value).setResponseCode(200)); +// JenkinsApi jenkinsApi = api(server.url("/").url(), AuthenticationType.UsernamePassword, usernamePassword); +// +// JenkinsAuthentication creds = creds(AuthenticationType.UsernamePassword, usernamePassword); +// JenkinsAuthenticationFilter filter = new JenkinsAuthenticationFilter(creds, jenkinsApi); +// HttpRequest httpRequest = HttpRequest.builder().endpoint(server.url("/").url().toString()).method("POST").build(); +// try { +// httpRequest = filter.filter(httpRequest); +// assertEquals(httpRequest.getEndpoint().toString(), server.url("/").url().toString()); +// assertSentAccept(server, "GET", "/crumbIssuer/api/xml?xpath=concat%28//crumbRequestField,%22%3A%22,//crumb%29", MediaType.TEXT_PLAIN); +// Multimap headers = httpRequest.getHeaders(); +// assertEquals(headers.size(), 3); +// assertTrue(headers.containsEntry("Jenkins-Crumb", value)); +// assertTrue(headers.containsEntry("Authorization", creds.authType().getAuthScheme() + " " + creds.authValue())); +// assertTrue(headers.containsEntry("Cookie", "")); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// @Test +// public void testUsernameApiTokenNeedsNoCrumb() throws Exception { +// MockWebServer server = mockWebServer(); +// +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// +// JenkinsAuthentication creds = creds(AuthenticationType.UsernameApiToken, "random_user:random_token"); +// JenkinsAuthenticationFilter filter = new JenkinsAuthenticationFilter(creds, jenkinsApi); +// HttpRequest httpRequest = HttpRequest.builder().endpoint(server.url("/").url().toString()).method("POST").build(); +// try { +// httpRequest = filter.filter(httpRequest); +// assertEquals(httpRequest.getEndpoint().toString(), server.url("/").url().toString()); +// Multimap headers = httpRequest.getHeaders(); +// assertEquals(headers.size(), 1); +// assertTrue(headers.containsEntry("Authorization", creds.authType().getAuthScheme() + " " + creds.authValue())); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +// +// @Test +// public void getMethodNeedsNoCrumb() throws Exception { +// MockWebServer server = mockWebServer(); +// +// JenkinsApi jenkinsApi = api(server.url("/").url()); +// +// JenkinsAuthentication creds = creds(AuthenticationType.UsernameApiToken, "random_user:random_token"); +// JenkinsAuthenticationFilter filter = new JenkinsAuthenticationFilter(creds, jenkinsApi); +// HttpRequest httpRequest = HttpRequest.builder().endpoint(server.url("/").url().toString()).method("GET").build(); +// try { +// httpRequest = filter.filter(httpRequest); +// assertEquals(httpRequest.getEndpoint().toString(), server.url("/").url().toString()); +// Multimap headers = httpRequest.getHeaders(); +// assertEquals(headers.size(), 1); +// assertTrue(headers.containsEntry("Authorization", creds.authType().getAuthScheme() + " " + creds.authValue())); +// } finally { +// jenkinsApi.close(); +// server.shutdown(); +// } +// } +//}