├── _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 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 | --------------------------------------------------------------------------------