├── _config.yml
├── .vscode
└── settings.json
├── .mvn
├── maven.config
└── extensions.xml
├── deploy
├── data.properties
├── run.bat
└── package.bat
├── src
└── main
│ ├── resources
│ ├── index.jelly
│ └── com
│ │ └── aq
│ │ └── aqconnect
│ │ └── AQPluginBuilderAction
│ │ ├── help-userName.html
│ │ ├── help-apiKey.html
│ │ ├── help-tenantCode.html
│ │ ├── help-jobId.html
│ │ ├── help-maxWaitTimeInMins.html
│ │ ├── help-runParamStr.html
│ │ ├── help-appURL.html
│ │ ├── help-stepFailureThreshold.html
│ │ └── config.jelly
│ └── java
│ └── com
│ └── aq
│ └── aqconnect
│ ├── AQException.java
│ ├── AQConstants.java
│ ├── AQFormValidate.java
│ ├── AQUtils.java
│ ├── AQRestClient.java
│ └── AQPluginBuilderAction.java
├── Jenkinsfile
├── .github
├── dependabot.yml
└── workflows
│ └── cd.yaml
├── README.md
├── .gitignore
├── nbactions.xml
├── .project
├── LICENSE
├── pom.xml
├── .classpath
├── .factorypath
└── aqconnect.iml
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "java.compile.nullAnalysis.mode": "automatic"
3 | }
--------------------------------------------------------------------------------
/.mvn/maven.config:
--------------------------------------------------------------------------------
1 | -Pconsume-incrementals
2 | -Pmight-produce-incrementals
3 | -Dchangelist.format=%d.v%s
--------------------------------------------------------------------------------
/deploy/data.properties:
--------------------------------------------------------------------------------
1 | project_location=C:\accelq\accelq-ci-connect-plugin
2 | jenkins_server_port=8955
--------------------------------------------------------------------------------
/src/main/resources/index.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 | ACCELQ Jenkins Plugin
4 |
5 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/help-userName.html:
--------------------------------------------------------------------------------
1 |
2 | Your ACCELQ User ID
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/help-apiKey.html:
--------------------------------------------------------------------------------
1 |
2 | API key available in Profile section of ACCELQ
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/help-tenantCode.html:
--------------------------------------------------------------------------------
1 |
2 | Tenant Code displayed in the Profile section of ACCELQ
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/help-jobId.html:
--------------------------------------------------------------------------------
1 |
2 | This ID should come from the CI job you saved in ACCELQ application
3 |
4 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/help-maxWaitTimeInMins.html:
--------------------------------------------------------------------------------
1 |
2 | Maximum time to wait for the job to be picked up by an ACCELQ Agent. Default is 15 mins.
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/help-runParamStr.html:
--------------------------------------------------------------------------------
1 |
2 | Run Params should be JSON string form example: {"username": "John Todd", "password": "bxW&=UVw"}
3 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/help-appURL.html:
--------------------------------------------------------------------------------
1 |
2 | Your ACCELQ Application URL in the exact following format:
3 |
4 |
https://<hostname>:<port_num>
5 |
--------------------------------------------------------------------------------
/Jenkinsfile:
--------------------------------------------------------------------------------
1 | buildPlugin(
2 | forkCount: '1C',
3 | useContainerAgent: true, // Set to `false` if you need to use Docker for containerized tests
4 | configurations: [
5 | [platform: 'linux', jdk: 21],
6 | [platform: 'windows', jdk: 17],
7 | ])
--------------------------------------------------------------------------------
/src/main/java/com/aq/aqconnect/AQException.java:
--------------------------------------------------------------------------------
1 | package com.aq.aqconnect;
2 |
3 |
4 | public class AQException extends RuntimeException{
5 |
6 | public AQException(String message) {
7 | super(String.format("[%s]", message), null, false, false);
8 | }
9 | }
--------------------------------------------------------------------------------
/deploy/run.bat:
--------------------------------------------------------------------------------
1 | echo off
2 | setlocal
3 |
4 | For /F "eol=# tokens=1,* delims==" %%A IN (data.properties) DO (
5 | set %%A=%%B
6 | )
7 |
8 |
9 | echo Starting Jenkins loaded with accelQ Plugin on Port 8954
10 | cd /d "%project_location%"
11 | call mvn hpi:run -Djetty.port=%jenkins_server_port%
12 |
13 | endlocal
14 | pause > nul
15 | exit
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuring-dependabot-version-updates
2 |
3 | version: 2
4 | updates:
5 | - package-ecosystem: maven
6 | directory: /
7 | schedule:
8 | interval: monthly
9 | - package-ecosystem: github-actions
10 | directory: /
11 | schedule:
12 | interval: monthly
13 |
--------------------------------------------------------------------------------
/deploy/package.bat:
--------------------------------------------------------------------------------
1 | echo off
2 | setlocal
3 |
4 | For /F "eol=# tokens=1,* delims==" %%A IN (data.properties) DO (
5 | set %%A=%%B
6 | )
7 |
8 | set temp=%project_location%\src\lib\core-1.0-SNAPSHOT.jar
9 |
10 | echo Packaging repo
11 | cd /d "%project_location%"
12 | call mvn install:install-file -Dfile="%temp%" -DgroupId=core -DartifactId=aqCore -Dversion=1.0 -Dpackaging=jar
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ACCELQ-Connect-Jenkins is a Jenkins Plugin to trigger automation suites after build.
2 |
3 | ### To Package
4 | Go to deploy folder and update the project location in data.properties file
5 | run package.bat
6 |
7 |
8 |
9 | ### To Run as standalone server
10 | Go to deploy folder and update the project location and port in data.properties file
11 | run deploy.bat
12 |
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/*
2 | work/*
3 | .idea/*
4 | aq-jenkins-connect.iml
5 | release.properties
6 | core/target/*
7 | core/.settings/org.eclipse.core.resources.prefs
8 | core/.settings/org.eclipse.jdt.core.prefs
9 | core/.settings/org.eclipse.jdt.apt.core.prefs
10 | core/.settings/org.eclipse.m2e.core.prefs
11 | release.properties
12 | core/target/maven-archiver/pom.properties
13 | core/core.iml
14 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/help-stepFailureThreshold.html:
--------------------------------------------------------------------------------
1 |
2 | Percentage ACCELQ test case failure, beyond which this Step in the Pipeline will be marked as a failure. If this is zero, even a single failed test will cause the Step to fail. If you never want to fail the Pipeline Step due to failing Automation tests, input -1. Input a valid integer between 0 and 100 or, -1.
3 |
--------------------------------------------------------------------------------
/.mvn/extensions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | io.jenkins.tools.incrementals
4 | git-changelist-maven-extension
5 | 1.7
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.github/workflows/cd.yaml:
--------------------------------------------------------------------------------
1 | # Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins
2 |
3 | name: cd
4 | on:
5 | workflow_dispatch:
6 | # check_run:
7 | # types:
8 | # - completed
9 |
10 | permissions:
11 | checks: read
12 | contents: write
13 |
14 | jobs:
15 | maven-cd:
16 | uses: jenkins-infra/github-reusable-workflows/.github/workflows/maven-cd.yml@v1
17 | secrets:
18 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
19 | MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }}
20 |
--------------------------------------------------------------------------------
/nbactions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | run
5 |
6 | hpi
7 |
8 |
9 | hpi:run
10 | -Djetty.port=8954
11 |
12 |
13 |
14 | debug
15 |
16 | hpi
17 |
18 |
19 | hpi:run
20 | -Djetty.port=8954
21 |
22 |
23 | maven
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | aqconnect
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.m2e.core.maven2Builder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.m2e.core.maven2Nature
22 |
23 |
24 |
25 | 1676955154322
26 |
27 | 30
28 |
29 | org.eclipse.core.resources.regexFilterMatcher
30 | node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 accelQ
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/main/resources/com/aq/aqconnect/AQPluginBuilderAction/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
40 |
--------------------------------------------------------------------------------
/src/main/java/com/aq/aqconnect/AQConstants.java:
--------------------------------------------------------------------------------
1 | package com.aq.aqconnect;
2 |
3 | public class AQConstants {
4 | public static final String LOG_DELIMITER = ">>> ";
5 | public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";
6 |
7 | public static final long JOB_STATUS_POLL_TIME = 30 * 1000;
8 | public static final int JOB_PICKUP_RETRY_TIME_THRESHOLD_IN_MINS = 15;
9 |
10 | public static final String JOB_WEB_LINK = "#/forward?entityType=9&resultId=%s";
11 | public static final String EXT_JOB_WEB_LINK = "#/resultext?tenant=%s&resultId=%s";
12 |
13 |
14 | public static final String API_VERSION = "1.0";
15 | public static final String AQ_RESULT_INFO_KEY = "AQReportInfo";
16 |
17 |
18 |
19 | public enum TEST_CASE_STATUS {
20 | PASS("pass"),
21 | FAIL("fail"),
22 | NOT_RUN("notRun"),
23 | RUNNING("running"),
24 | INFO("info"),
25 | FATAL("fatal"),
26 | WARN("warn"),
27 | ALL("all");
28 |
29 | private String status;
30 | TEST_CASE_STATUS(String status) {
31 | this.status = status;
32 | }
33 | public String getStatus() { return status; }
34 | }
35 |
36 | public enum TEST_JOB_STATUS {
37 | NOT_APPLICABLE("Not Applicable"),
38 | SCHEDULED("Scheduled"),
39 | IN_PROGRESS("In Progress"),
40 | COMPLETED("Completed"),
41 | ABORTED("Aborted"),
42 | FAILED("Failed To Start"),
43 | RECURRING("Recurring"),
44 | ERROR("Error"),
45 | CONTINUOUS_INTEGRATION("Continuous Integration");
46 |
47 | private String status;
48 | TEST_JOB_STATUS(String status) {
49 | this.status = status;
50 | }
51 | public String getStatus() { return status; }
52 |
53 | }
54 | }
--------------------------------------------------------------------------------
/src/main/java/com/aq/aqconnect/AQFormValidate.java:
--------------------------------------------------------------------------------
1 | package com.aq.aqconnect;
2 |
3 |
4 | import java.net.URL;
5 | import java.util.regex.Pattern;
6 |
7 | public class AQFormValidate {
8 |
9 | public String validateJobID(String value) {
10 | try {
11 | int x = Integer.parseInt(value);
12 | if (x <= 0) {
13 | return "Must be a number greater than 0";
14 | }
15 | }
16 | catch (NumberFormatException e) {
17 | return "Not a number";
18 | }
19 | return null;
20 |
21 | }
22 | public String validateTenantCode(String value) {
23 | return this.validateGenericField(value);
24 | }
25 | public String validateAppURL(String value) {
26 | try {
27 | new URL(value);
28 | }
29 | catch (Exception e) {
30 | return "Not a URL";
31 | }
32 | return null;
33 | }
34 | public String validateGenericField(String value) {
35 | try {
36 | if (value == null || value.length() == 0)return "Cannot be empty";
37 | }
38 | catch (Exception e) {
39 | return "Cannot be empty";
40 | }
41 | return null;
42 | }
43 | public String validateAPIKey(String value) {
44 | return this.validateGenericField(value);
45 | }
46 | public String validateUserId(String value) {
47 | try {
48 | String emailRegex = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@"
49 | + "[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
50 | Pattern pat = Pattern.compile(emailRegex);
51 | if (value == null || value.length() == 0) return "Cannot be empty";
52 | else if (!pat.matcher(value).matches()) return "User ID must be in email format";
53 | }catch(Exception e) {}
54 | return null;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.jenkins-ci.plugins
7 | plugin
8 | 4.73
9 |
10 |
11 |
12 | com.aq
13 | accelq-ci-connect
14 | ${changelist}
15 | hpi
16 |
17 |
18 | 999999-SNAPSHOT
19 | jenkinsci/accelq-ci-connect-plugin
20 | 2.401.3
21 | 11
22 |
23 | hpi
24 |
25 |
26 | ACCELQ CI-Connect Plugin
27 | http://www.accelq.com
28 |
29 | https://github.com/${gitHubRepo}
30 | scm:git:https://github.com/${gitHubRepo}.git
31 | scm:git:git@github.com:${gitHubRepo}.git
32 | ${scmTag}
33 |
34 |
35 |
36 | accelq
37 | accelq
38 | info@accelq.com
39 |
40 |
41 |
42 |
43 |
44 | MIT License
45 | http://opensource.org/licenses/MIT
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | repo.jenkins-ci.org
54 | https://repo.jenkins-ci.org/public/
55 |
56 |
57 |
58 |
59 | repo.jenkins-ci.org
60 | https://repo.jenkins-ci.org/public/
61 |
62 |
63 |
64 | ${project.artifactId}-${project.version}
65 |
66 |
67 |
68 | org.apache.httpcomponents
69 | httpclient
70 | [4.5.2,)
71 |
72 |
73 | com.googlecode.json-simple
74 | json-simple
75 | [1.1.1,)
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/src/main/java/com/aq/aqconnect/AQUtils.java:
--------------------------------------------------------------------------------
1 | package com.aq.aqconnect;
2 | import org.apache.http.entity.StringEntity;
3 | import org.json.simple.JSONObject;
4 | import org.json.simple.parser.JSONParser;
5 | import org.json.simple.parser.ParseException;
6 |
7 | import java.util.Date;
8 |
9 |
10 | public class AQUtils {
11 | public StringEntity getRunParam(String jobId, String runParam, int expireTimeInMinutes) throws ParseException {
12 | JSONObject jsonObj = new JSONObject();
13 | if(runParam != null && !runParam.equals("")) {
14 | jsonObj.put("runProperties", (JSONObject) new JSONParser().parse(runParam));
15 | }
16 | jsonObj.put("jobPid", Integer.parseInt(jobId));
17 | jsonObj.put("expireTimeInMinutes", expireTimeInMinutes);
18 | StringEntity requestEntity = new StringEntity(jsonObj.toJSONString(), org.apache.http.entity.ContentType.APPLICATION_JSON);
19 | return requestEntity;
20 | }
21 | public String getRunParamJsonPayload(String runParamStr) {
22 | if(runParamStr == null || runParamStr.trim().length() == 0)
23 | return null;
24 | try {
25 | new JSONParser().parse(runParamStr);
26 | return runParamStr;
27 | }catch(Exception e) {
28 | JSONObject json = new JSONObject();
29 | String[] splitOnAmp = runParamStr.split("&");
30 | for(String split: splitOnAmp) {
31 | String[] splitOnEquals = split.split("=");
32 | if(splitOnEquals.length == 2) {
33 | String key = splitOnEquals[0].trim(), value = splitOnEquals[1].trim();
34 | if(!key.equals("") && !value.equals("")) {
35 | json.put(key, value);
36 | }
37 | }
38 | }
39 | return json.toJSONString();
40 | }
41 |
42 | }
43 | public String getFormattedTime(long a, long b) {
44 | Date startDate = new Date(a);
45 | Date endDate = new Date(b);
46 | long difference_In_Time
47 | = endDate.getTime() - startDate.getTime();
48 | long difference_In_Seconds
49 | = (difference_In_Time
50 | / 1000)
51 | % 60;
52 | long difference_In_Minutes
53 | = (difference_In_Time
54 | / (1000 * 60))
55 | % 60;
56 | long difference_In_Hours
57 | = (difference_In_Time
58 | / (1000 * 60 * 60))
59 | % 24;
60 | long difference_In_Days
61 | = (difference_In_Time
62 | / (1000 * 60 * 60 * 24))
63 | % 365;
64 | String res = "";
65 | if (difference_In_Days != Long.valueOf(0)) {
66 | res += (difference_In_Days > Long.valueOf(1) ? (difference_In_Days + " days") : (difference_In_Days + " day"));
67 | }
68 | if (difference_In_Hours != Long.valueOf(0)) {
69 | res += (difference_In_Hours > Long.valueOf(1) ? (difference_In_Hours + " hrs") : (difference_In_Hours + " hr"));
70 | }
71 | if (difference_In_Minutes != Long.valueOf(0)) {
72 | res += " " + (difference_In_Minutes > Long.valueOf(1) ? (difference_In_Minutes + " mins") : (difference_In_Minutes + " min"));
73 | }
74 | if (difference_In_Seconds != Long.valueOf(0)) {
75 | res += " " + (difference_In_Seconds > Long.valueOf(1) ? (difference_In_Seconds + " seconds") : (difference_In_Seconds + " second"));
76 | }
77 | return res;
78 | }
79 | public boolean isWaitTimeExceeded(long start, int maxWait) {
80 | return Math.floor((double)(System.currentTimeMillis() - start) / (1000 * 60)) > maxWait;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/com/aq/aqconnect/AQRestClient.java:
--------------------------------------------------------------------------------
1 | package com.aq.aqconnect;
2 |
3 |
4 | import org.apache.http.HttpHost;
5 | import org.apache.http.HttpStatus;
6 | import org.apache.http.client.methods.CloseableHttpResponse;
7 | import org.apache.http.client.methods.HttpGet;
8 | import org.apache.http.client.methods.HttpPost;
9 | import org.apache.http.client.methods.HttpPut;
10 | import org.apache.http.conn.ssl.DefaultHostnameVerifier;
11 | import org.apache.http.conn.ssl.NoopHostnameVerifier;
12 | import org.apache.http.impl.client.CloseableHttpClient;
13 | import org.apache.http.impl.client.HttpClientBuilder;
14 | import org.apache.http.impl.client.HttpClients;
15 | import org.apache.http.ssl.SSLContextBuilder;
16 | import org.apache.http.ssl.TrustStrategy;
17 | import org.json.simple.JSONArray;
18 | import org.json.simple.JSONObject;
19 | import org.json.simple.parser.JSONParser;
20 | import org.json.simple.parser.ParseException;
21 |
22 | import javax.net.ssl.SSLContext;
23 | import java.io.BufferedReader;
24 | import java.io.IOException;
25 | import java.io.InputStreamReader;
26 | import java.nio.charset.StandardCharsets;
27 | import java.security.KeyManagementException;
28 | import java.security.KeyStoreException;
29 | import java.security.NoSuchAlgorithmException;
30 | import java.security.cert.CertificateException;
31 | import java.security.cert.X509Certificate;
32 |
33 | public class AQRestClient {
34 |
35 |
36 | private final JSONParser jsonParser = new JSONParser();
37 |
38 | //Base URL and extensions
39 | private String BASE_URL;
40 | private String API_ENDPOINT;
41 | private int PROXY_PORT = 80;
42 | private String PROXY_HOST;
43 | private Boolean DISABLE_SSL_CHECKS = false;
44 |
45 |
46 | public String getBaseURL() {
47 | return BASE_URL;
48 | }
49 |
50 | public void setUpBaseURL(String baseURL, String tenantCode) {
51 | BASE_URL = baseURL.charAt(baseURL.length() - 1) == '/'?(baseURL):(baseURL + '/');
52 | API_ENDPOINT = BASE_URL + "awb/api/" + AQConstants.API_VERSION + "/" + tenantCode;
53 | }
54 |
55 | private CloseableHttpClient getHttpsClient(){
56 | try {
57 | HttpClientBuilder hcb = null;
58 | if (DISABLE_SSL_CHECKS) {
59 | SSLContext sslContext = new SSLContextBuilder()
60 | .loadTrustMaterial(null, new TrustStrategy() {
61 | @Override
62 | public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
63 | return true;
64 | }
65 | }).build();
66 | hcb = HttpClients.custom()
67 | .setSSLContext(sslContext)
68 | .setSSLHostnameVerifier(new NoopHostnameVerifier());
69 | } else {
70 | hcb = HttpClients.custom()
71 | .setSSLContext(SSLContext.getDefault())
72 | .setSSLHostnameVerifier(new DefaultHostnameVerifier());
73 | }
74 | if (PROXY_HOST != null && !PROXY_HOST.equals("")) {
75 | HttpHost hh = new HttpHost(PROXY_HOST, PROXY_PORT);
76 | hcb.setProxy(hh);
77 | }
78 | CloseableHttpClient client = hcb.build();
79 | return client;
80 | }catch(NoSuchAlgorithmException e){
81 | return null;
82 | }catch(KeyStoreException e){
83 | return null;
84 | }catch(KeyManagementException e){
85 | return null;
86 | }
87 | }
88 |
89 | public JSONObject getJobSummary(long runPid, String apiKey, String userId) {
90 | CloseableHttpClient httpClient = getHttpsClient();
91 |
92 | HttpGet httpGet = new HttpGet(API_ENDPOINT + "/runs/" + runPid);
93 | httpGet.addHeader("User-Agent", AQConstants.USER_AGENT);
94 | httpGet.addHeader("API_KEY", apiKey);
95 | httpGet.addHeader("USER_ID", userId);
96 | httpGet.addHeader("Content-Type", "application/json");
97 | try {
98 | CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
99 | int statusCode = httpResponse.getStatusLine().getStatusCode();
100 | if (statusCode >= 200 && statusCode <= 299) {
101 | BufferedReader reader = new BufferedReader(new InputStreamReader(
102 | httpResponse.getEntity().getContent(), StandardCharsets.UTF_8));
103 | String inputLine;
104 | StringBuffer response = new StringBuffer();
105 |
106 | while ((inputLine = reader.readLine()) != null) {
107 | response.append(inputLine);
108 | }
109 | reader.close();
110 | JSONObject summaryObj = (JSONObject) jsonParser.parse(response.toString());
111 | httpClient.close();
112 | return summaryObj;
113 | } else {
114 | JSONObject errorObj = new JSONObject();
115 | errorObj.put("aq_statusCode", statusCode);
116 | httpClient.close(); // Close the HttpClient here in the error case
117 | return errorObj;
118 | }
119 | } catch(IOException ioe) {
120 | ioe.printStackTrace();
121 | return null;
122 | } catch (ParseException pe) {
123 | pe.printStackTrace();
124 | return null;
125 | }
126 | }
127 |
128 | public JSONObject triggerJob(String apiKey, String userId, String jobId, String runParam, int maxWaitTime) throws IOException,
129 | ParseException {
130 | CloseableHttpClient httpClient = getHttpsClient();
131 | HttpPut httpPut = new HttpPut(API_ENDPOINT + "/jobs/" + jobId + "/trigger-ci-job?passcode=true");
132 | httpPut.addHeader("User-Agent", AQConstants.USER_AGENT);
133 | httpPut.addHeader("API_KEY", apiKey);
134 | httpPut.addHeader("USER_ID", userId);
135 | httpPut.addHeader("Content-Type", "application/json");
136 | httpPut.setEntity(new AQUtils().getRunParam(jobId, runParam, maxWaitTime));
137 | try {
138 | CloseableHttpResponse httpResponse = httpClient.execute(httpPut);
139 | BufferedReader reader = new BufferedReader(new InputStreamReader(
140 | httpResponse.getEntity().getContent(), StandardCharsets.UTF_8));
141 | String inputLine;
142 | StringBuffer response = new StringBuffer();
143 | while ((inputLine = reader.readLine()) != null) {
144 | response.append(inputLine);
145 | }
146 | reader.close();
147 | JSONObject jobInfo = (JSONObject) jsonParser.parse(response.toString());
148 | if (httpResponse.getStatusLine().getStatusCode() == 200 || httpResponse.getStatusLine().getStatusCode() == 204) {
149 | return jobInfo;
150 | } else {
151 | // error object
152 | return (JSONObject) jsonParser.parse(response.toString());
153 | }
154 | } catch(IOException ioe) {
155 | ioe.printStackTrace();
156 | return null;
157 | } catch (Exception pe) {
158 | pe.printStackTrace();
159 | return null;
160 | } finally {
161 | httpClient.close();
162 | }
163 | }
164 |
165 | public String testConnection(String apiKey, String userId, String jobId, String runParam, int maxWaitTime)
166 | throws ParseException, IOException {
167 | CloseableHttpClient httpClient = getHttpsClient();
168 | HttpPost httpPost = new HttpPost(API_ENDPOINT + "/jobs/" + jobId + "/validate-ci-job");
169 | httpPost.addHeader("User-Agent", AQConstants.USER_AGENT);
170 | httpPost.addHeader("API_KEY", apiKey);
171 | httpPost.addHeader("USER_ID", userId);
172 | httpPost.addHeader("Content-Type", "application/json");
173 | httpPost.setEntity(new AQUtils().getRunParam(jobId, runParam, maxWaitTime));
174 | try {
175 | CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
176 | if (httpResponse.getStatusLine().getStatusCode() == 200 || httpResponse.getStatusLine().getStatusCode() == 204) {
177 | return "";
178 | }
179 | if(httpResponse.getStatusLine().getStatusCode() == 404) {
180 | return "Connection request failed. Please check the URL and Tenant Code.";
181 | }
182 | if (httpResponse.getStatusLine().getStatusCode() == 401) {
183 | // user id and api key is wrong
184 | return "Connection request failed. Please check connection parameters.";
185 | } else if (httpResponse.getStatusLine().getStatusCode() != 200){
186 | return "Template Job ID does not exist.";
187 | }
188 | return "";
189 | } catch(IOException ioe) {
190 | ioe.printStackTrace();
191 | return null;
192 | } catch (Exception pe) {
193 | pe.printStackTrace();
194 | return null;
195 | } finally {
196 | httpClient.close();
197 | }
198 | }
199 |
200 | public void setUpProxy(String proxyHost, int proxyPort) {
201 | PROXY_HOST = proxyHost;
202 | PROXY_PORT = proxyPort == 0 ? 80 : proxyPort;
203 | }
204 |
205 | public void disableSSLChecks(Boolean check) {
206 | DISABLE_SSL_CHECKS = check || false;
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/.factorypath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/src/main/java/com/aq/aqconnect/AQPluginBuilderAction.java:
--------------------------------------------------------------------------------
1 | package com.aq.aqconnect;
2 |
3 | import hudson.Extension;
4 | import hudson.FilePath;
5 | import hudson.Launcher;
6 | import hudson.Util;
7 | import hudson.model.*;
8 | import hudson.util.Secret;
9 | import hudson.tasks.BuildStepDescriptor;
10 | import hudson.tasks.BuildStepMonitor;
11 | import hudson.tasks.Publisher;
12 | import hudson.tasks.Recorder;
13 | import hudson.util.FormValidation;
14 | import jenkins.model.Jenkins;
15 | import jenkins.tasks.SimpleBuildStep;
16 | import org.kohsuke.stapler.AncestorInPath;
17 | import org.kohsuke.stapler.DataBoundConstructor;
18 | import org.apache.commons.lang.StringUtils;
19 | import org.json.simple.*;
20 | import edu.umd.cs.findbugs.annotations.NonNull;
21 | import javax.servlet.ServletException;
22 | import java.io.IOException;
23 | import java.io.PrintStream;
24 | import org.kohsuke.stapler.QueryParameter;
25 | import org.kohsuke.stapler.verb.POST;
26 | import org.json.simple.parser.ParseException;
27 |
28 |
29 | public class AQPluginBuilderAction extends Recorder implements SimpleBuildStep {
30 |
31 | private String jobId;
32 | private Secret apiKey;
33 | private String appURL;
34 | private String userName;
35 | private String tenantCode;
36 | //run params
37 | private String runParamStr;
38 | private String proxyHost;
39 | private String proxyPort;
40 | private String stepFailureThreshold;
41 | private String maxWaitTimeInMins;
42 | private Boolean disableSSLCheck;
43 |
44 | @DataBoundConstructor
45 | public AQPluginBuilderAction(String jobId, Secret apiKey, String appURL, String runParamStr,
46 | String tenantCode, String userName, String proxyHost, String proxyPort, String stepFailureThreshold, String maxWaitTimeInMins, Boolean disableSSLCheck) {
47 | this.jobId = jobId;
48 | this.apiKey = apiKey;
49 | this.appURL = appURL;
50 | this.runParamStr = runParamStr;
51 | this.tenantCode = tenantCode;
52 | this.userName = userName;
53 | this.proxyPort = proxyPort;
54 | this.proxyHost = proxyHost;
55 | this.stepFailureThreshold = stepFailureThreshold;
56 | this.maxWaitTimeInMins = maxWaitTimeInMins;
57 | this.disableSSLCheck = disableSSLCheck || false;
58 | }
59 |
60 | public Secret getApiKey() {
61 | return apiKey;
62 | }
63 | public String getUserName() {
64 | return userName;
65 | }
66 |
67 | public String getJobId() {
68 | return jobId;
69 | }
70 |
71 | public String getAppURL() {
72 | return appURL;
73 | }
74 |
75 | public String getRunParamStr() {
76 | return runParamStr;
77 | }
78 |
79 | public String getProxyPort() {
80 | return proxyPort;
81 | }
82 |
83 | public String getProxyHost() {
84 | return proxyHost;
85 | }
86 |
87 | public String getTenantCode() {
88 | return tenantCode;
89 | }
90 | public String getStepFailureThreshold() {
91 | return stepFailureThreshold;
92 | }
93 | public String getMaxWaitTimeInMins() {
94 | return maxWaitTimeInMins;
95 | }
96 | public Boolean getSSLChecks() {
97 | return disableSSLCheck;
98 | }
99 |
100 | @Override
101 | public DescriptorImpl getDescriptor() {
102 | return (DescriptorImpl) super.getDescriptor();
103 | }
104 |
105 | @Override
106 | public void perform(@NonNull Run, ?> run, @NonNull FilePath workspace, @NonNull Launcher launcher,
107 | @NonNull TaskListener listener) throws InterruptedException, IOException {
108 | PrintStream out = listener.getLogger();
109 | AQRestClient aqRestClient = null;
110 | JSONObject summaryObj = null;
111 | long realJobPid = 0;
112 | try {
113 | aqRestClient = new AQRestClient();
114 | AQUtils aqUtils = new AQUtils();
115 | aqRestClient.setUpBaseURL(this.appURL, this.tenantCode);
116 | aqRestClient.disableSSLChecks(this.disableSSLCheck);
117 | if (this.proxyHost != null && this.proxyPort != null && this.proxyHost.length() > 0 && this.proxyPort.length() > 0) {
118 | aqRestClient.setUpProxy(this.proxyHost.trim(), Integer.parseInt(this.proxyPort.trim()));
119 | } else {
120 | aqRestClient.setUpProxy("", 0);
121 | }
122 | out.println("******************************************");
123 | out.println("*** Begin: ACCELQ Test Automation Step ***");
124 | out.println("******************************************");
125 | out.println();
126 | String runParamJsonPayload = aqUtils.getRunParamJsonPayload(this.runParamStr);
127 | int maxWaitTime = 0;
128 | if (this.maxWaitTimeInMins == null || this.maxWaitTimeInMins.equals("")) {
129 | maxWaitTime = AQConstants.JOB_PICKUP_RETRY_TIME_THRESHOLD_IN_MINS;
130 | } else {
131 | maxWaitTime = Integer.parseInt(this.maxWaitTimeInMins);
132 | }
133 | // Test connection at runtime
134 | String res = aqRestClient.testConnection(this.apiKey.getPlainText(), this.userName, this.jobId, runParamJsonPayload, maxWaitTime);
135 | if (res == null) {
136 | throw new AQException("Connection Error: Something in plugin went wrong");
137 | } else if(res.length() > 0) {
138 | throw new AQException("Connection Error: " + res);
139 | }
140 | JSONObject realJobObj = aqRestClient.triggerJob(this.apiKey.getPlainText(), this.userName, this.jobId, runParamJsonPayload, maxWaitTime);
141 |
142 | if (realJobObj == null) {
143 | throw new AQException("Unable to submit the Job, check plugin log stack");
144 | }
145 | if (realJobObj.get("cause") != null) {
146 | throw new AQException((String)realJobObj.get("cause"));
147 | }
148 | realJobPid = (long) realJobObj.get("jobPid");
149 | long passCount = 0, failCount = 0, totalCount = 0, notRunCount = 0;
150 | String jobStatus = "";
151 | int attempt = 0;
152 | final long startTime = System.currentTimeMillis();
153 | String threshold = this.stepFailureThreshold;
154 | if (threshold == null || threshold.equals("")) {
155 | threshold = "0";
156 | }
157 | boolean isDouble = threshold.indexOf(".") != -1;
158 | int failureThreshold = isDouble ? Double.valueOf(threshold).intValue() : Integer.parseInt(threshold);
159 |
160 | String resultAccessURL = (String) realJobObj.get("extResultUrlWithApiCode");
161 | String resultLinkPasscode = (String) realJobObj.get("extResultUrlPasscode");
162 | boolean error = false;
163 | boolean hasLoggedLinks = false;
164 | do {
165 | summaryObj = aqRestClient.getJobSummary(realJobPid, this.apiKey.getPlainText(), this.userName);
166 | if (summaryObj.containsKey("aq_statusCode")) {
167 | error = true;
168 | out.println("Warn: Issue fetching Job Summary, Status Code: " + summaryObj.get("aq_statusCode"));
169 | } else {
170 | error = false;
171 | }
172 |
173 | if (!error) {
174 | if (summaryObj.get("cause") != null) {
175 | throw new AQException((String) summaryObj.get("cause"));
176 | }
177 | if (summaryObj.get("summary") != null) {
178 | summaryObj = (JSONObject) summaryObj.get("summary");
179 | }
180 | passCount = (Long) summaryObj.get("pass");
181 | failCount = (Long) summaryObj.get("fail");
182 | notRunCount = (Long) summaryObj.get("notRun");
183 | if (attempt == 0) {
184 | attempt = 1;
185 | String jobPurpose = (String) summaryObj.get("purpose");
186 | String scenarioName = (String) summaryObj.get("scnName");
187 | String testSuiteName = (String) summaryObj.get("testSuiteName");
188 | Long totalTestCases = (Long) summaryObj.get("testcaseCount");
189 | if (testSuiteName != null && testSuiteName.length() > 0) {
190 | out.println("Test Suite Name: " + testSuiteName);
191 | } else {
192 | out.println("Scenario Name: " + scenarioName);
193 | }
194 | out.println("Purpose: " + jobPurpose);
195 | out.println("Total Test Cases: " + totalTestCases);
196 | out.println("Step Failure threshold: " + threshold);
197 | out.println("Max Wait Time in Minutes: " + maxWaitTime);
198 | out.println();
199 | if (isDouble) {
200 | out.println("Warning: Invalid value (" + threshold +") passed for Step Failure Threshold. Truncating the value to " + failureThreshold + " (Only integers between 0 and 100, and -1 are allowed).");
201 | }
202 | if (failureThreshold <= -2 || failureThreshold >= 101) {
203 | out.println("Warning: Ignoring the Step Failure threshold. Invalid value (" + failureThreshold + ") passed. Valid values are 0 to 100, or -1 to ignore threshold.");
204 | failureThreshold = 0;
205 | }
206 | }
207 | jobStatus = ((String) summaryObj.get("status")).toUpperCase();
208 | if (!jobStatus.equals(AQConstants.TEST_JOB_STATUS.SCHEDULED.getStatus().toUpperCase()) && !hasLoggedLinks) {
209 | hasLoggedLinks = true;
210 | out.println("Results Link: " + resultAccessURL);
211 | if (!StringUtils.isBlank(resultLinkPasscode)) {
212 | out.println("Results Link Passcode: " + resultLinkPasscode);
213 | }
214 | out.println("Need to abort? Click on the link above, login to ACCELQ and abort the run.");
215 | out.println();
216 | }
217 | if (jobStatus.equals(AQConstants.TEST_JOB_STATUS.COMPLETED.getStatus().toUpperCase())) {
218 | res = " " + aqUtils.getFormattedTime((Long)summaryObj.get("startTimestamp"), (Long)summaryObj.get("completedTimestamp"));
219 | out.println("Status: " + summaryObj.get("status").toString().toUpperCase() + " ("+res.trim()+")");
220 | } else {
221 | out.println("Status: " + summaryObj.get("status").toString().toUpperCase());
222 | }
223 |
224 | if (hasLoggedLinks) {
225 | totalCount = passCount + failCount + notRunCount;
226 | out.println("Total " + totalCount + ": "
227 | + "" + passCount +" Pass / " + failCount + " Fail");
228 | out.println();
229 | }
230 | if(jobStatus.equals(AQConstants.TEST_JOB_STATUS.SCHEDULED.getStatus().toUpperCase()) && aqUtils.isWaitTimeExceeded(startTime,maxWaitTime)) {
231 | throw new AQException(AQConstants.LOG_DELIMITER + "No agent available to pickup the job");
232 | }
233 | }
234 | Thread.sleep(AQConstants.JOB_STATUS_POLL_TIME);
235 | } while (!jobStatus.equals(AQConstants.TEST_JOB_STATUS.COMPLETED.getStatus().toUpperCase())
236 | && !jobStatus.equals(AQConstants.TEST_JOB_STATUS.ABORTED.getStatus().toUpperCase())
237 | && !jobStatus.equals(AQConstants.TEST_JOB_STATUS.FAILED.getStatus().toUpperCase())
238 | && !jobStatus.equals(AQConstants.TEST_JOB_STATUS.ERROR.getStatus().toUpperCase()));
239 | out.println("Results Link: " + resultAccessURL);
240 | if (!StringUtils.isBlank(resultLinkPasscode)) {
241 | out.println("Results Link Passcode: " + resultLinkPasscode);
242 | }
243 | out.println();
244 |
245 | double failCount_ = Long.valueOf(failCount).doubleValue();
246 | double totalCount_ = Long.valueOf(totalCount).doubleValue();
247 | int failedPercentage = (int) ((failCount_ / totalCount_) * 100);
248 |
249 | if (jobStatus.equals(AQConstants.TEST_JOB_STATUS.ABORTED.getStatus().toUpperCase())
250 | || jobStatus.equals(AQConstants.TEST_JOB_STATUS.FAILED.getStatus().toUpperCase())
251 | || jobStatus.equals(AQConstants.TEST_JOB_STATUS.ERROR.getStatus().toUpperCase())) {
252 | throw new AQException(AQConstants.LOG_DELIMITER + "Run Failed");
253 | } else if(failCount > 0) {
254 | if(failureThreshold != -1 && failedPercentage >= failureThreshold) {
255 | throw new AQException(AQConstants.LOG_DELIMITER + "Automation test step failed (test case failure count exceeds the threshold limit)");
256 | }
257 | }
258 | run.setResult(Result.SUCCESS);
259 | } catch (ParseException e) {
260 | out.println(e);
261 | run.setResult(Result.FAILURE);
262 | } finally {
263 | out.println("**********************************************");
264 | out.println("*** Completed: ACCELQ Test Automation Step ***");
265 | out.println("**********************************************");
266 | out.println();
267 | }
268 | }
269 |
270 | @Override
271 | public BuildStepMonitor getRequiredMonitorService() {
272 | return BuildStepMonitor.NONE;
273 | }
274 |
275 | @Extension
276 | public static final class DescriptorImpl extends BuildStepDescriptor {
277 |
278 | public DescriptorImpl() {
279 | load();
280 | }
281 |
282 | @POST
283 | public FormValidation doTestConnection(@QueryParameter("appURL") final String appURL,
284 | @QueryParameter("apiKey") final String apiKey,
285 | @QueryParameter("jobId") final String jobId,
286 | @QueryParameter("userName") final String userName,
287 | @QueryParameter("tenantCode") final String tenantCode,
288 | @QueryParameter("runParamStr") final String runParamStr,
289 | @QueryParameter("proxyHost") final String proxyHost,
290 | @QueryParameter("proxyPort") final String proxyPort,
291 | @QueryParameter("stepFailureThreshold") final String stepFailureThreshold,
292 | @QueryParameter("maxWaitTimeInMins") final String maxWaitTimeInMins,
293 | @QueryParameter("disableSSLCheck") final Boolean disableSSLCheck,
294 | @AncestorInPath Job job) throws IOException, ServletException {
295 |
296 | Jenkins.get().checkPermission(Jenkins.ADMINISTER);
297 | // basic form validate
298 | AQFormValidate formValidate = new AQFormValidate();
299 | String emptyError = "Cannot be empty";
300 | if (Util.fixEmptyAndTrim(appURL) == null) {
301 | return FormValidation.error("ACCELQ App URL: " + emptyError);
302 | }
303 | String res = formValidate.validateAppURL(appURL);
304 | if (res != null) {
305 | return FormValidation.error("ACCELQ App URL: " + res);
306 | }
307 | if (Util.fixEmptyAndTrim(userName) == null) {
308 | return FormValidation.error("ACCELQ User ID: " + emptyError);
309 | }
310 | res = formValidate.validateUserId(userName);
311 | if (res != null) {
312 | return FormValidation.error("ACCELQ User ID: " + res);
313 | }
314 | if (Util.fixEmptyAndTrim(apiKey) == null) {
315 | return FormValidation.error("API Key: " + emptyError);
316 | }
317 | res = formValidate.validateAPIKey(apiKey);
318 | if (res != null) {
319 | return FormValidation.error("API Key: " + res);
320 | }
321 | if (Util.fixEmptyAndTrim(appURL) == null) {
322 | return FormValidation.error("Tenant Code: " + emptyError);
323 | }
324 | res = formValidate.validateTenantCode(tenantCode);
325 | if (res != null) {
326 | return FormValidation.error("Tenant Code: " + res);
327 | }
328 | if (Util.fixEmptyAndTrim(appURL) == null) {
329 | return FormValidation.error("ACCELQ CI Job ID: " + emptyError);
330 | }
331 | res = formValidate.validateJobID(jobId);
332 | if (res != null) {
333 | return FormValidation.error("ACCELQ CI Job ID: " + res);
334 | }
335 | try {
336 | int maxWaitTime = 0;
337 | if (maxWaitTimeInMins == null || maxWaitTimeInMins.equals("")) {
338 | maxWaitTime = AQConstants.JOB_PICKUP_RETRY_TIME_THRESHOLD_IN_MINS;
339 | } else {
340 | maxWaitTime = Integer.parseInt(maxWaitTimeInMins);
341 | }
342 | // make call to backend to validate it
343 | AQRestClient aqRestClient = null;
344 | AQUtils aqUtils = new AQUtils();
345 | aqRestClient = new AQRestClient();
346 | String payload = aqUtils.getRunParamJsonPayload(runParamStr);
347 | aqRestClient.setUpBaseURL(appURL, tenantCode);
348 | aqRestClient.disableSSLChecks(disableSSLCheck);
349 | if (proxyHost != null && proxyPort != null && proxyHost.length() > 0 && proxyPort.length() > 0) {
350 | aqRestClient.setUpProxy(proxyHost.trim(), Integer.parseInt(proxyPort.trim()));
351 | } else {
352 | aqRestClient.setUpProxy("", 0);
353 | }
354 | res = aqRestClient.testConnection(apiKey, userName, jobId, payload, maxWaitTime);
355 | if (res == null) {
356 | return FormValidation.error("Connection Error: Something in plugin went wrong");
357 | } else if(res.length() > 0) {
358 | return FormValidation.error("Connection Error: " + res);
359 | }
360 | }catch (Exception e) {
361 | return FormValidation.error("Connection error: "+e.getMessage());
362 | }
363 | return FormValidation.ok("Success");
364 | }
365 |
366 | public boolean isApplicable(Class extends AbstractProject> aClass) {
367 | return true;
368 | }
369 |
370 | public String getDisplayName() {
371 | return "ACCELQ Connect";
372 | }
373 |
374 | }
375 |
376 | }
377 |
--------------------------------------------------------------------------------
/aqconnect.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
--------------------------------------------------------------------------------