diff --git a/.gitignore b/.gitignore
index 8b8928d..74479fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,6 +40,9 @@ buildNumber.properties
## Plugin-specific files:
+# VS Code
+.vscode
+
# IntelliJ
/out/
diff --git a/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.jar.md5 b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.jar.md5
new file mode 100644
index 0000000..6d13c5e
--- /dev/null
+++ b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.jar.md5
@@ -0,0 +1 @@
+6c754e433587ea29f749e3d89e359d68
\ No newline at end of file
diff --git a/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.jar.sha1 b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.jar.sha1
new file mode 100644
index 0000000..d92f29c
--- /dev/null
+++ b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.jar.sha1
@@ -0,0 +1 @@
+c200e4c488c2c195d7e9419426963ee0d3f50e3a
\ No newline at end of file
diff --git a/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom
new file mode 100644
index 0000000..706aa89
--- /dev/null
+++ b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+ com.ibm.cloud.urbancode
+ cloud-connect-java
+ 1.0.920563
+
+
+ org.apache.wink
+ wink-json4j
+ 1.4
+ compile
+
+
+ io.socket
+ socket.io-client
+ 0.7.0
+ compile
+
+
+ commons-codec
+ commons-codec
+ 1.10
+ compile
+
+
+ log4j
+ log4j
+ 1.2.17
+ compile
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
diff --git a/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom.md5 b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom.md5
new file mode 100644
index 0000000..fce6216
--- /dev/null
+++ b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom.md5
@@ -0,0 +1 @@
+02ccf932b56ed69bb01318c1d83520f9
\ No newline at end of file
diff --git a/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom.sha1 b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom.sha1
new file mode 100644
index 0000000..47424c1
--- /dev/null
+++ b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/cloud-connect-java-1.0.920563.pom.sha1
@@ -0,0 +1 @@
+25c902c0b385cd671c01d25a197e36c4ab6111b4
\ No newline at end of file
diff --git a/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/maven-metadata.xml b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/maven-metadata.xml
new file mode 100644
index 0000000..83a0c8c
--- /dev/null
+++ b/lib/uc-cloud-connect-java/cloud-connect-java/1.0.920563/maven-metadata.xml
@@ -0,0 +1,11 @@
+
+
+ uc-cloud-connect-java
+ cloud-connect-java
+
+
+ 1.0.920563
+
+ 20150821193926
+
+
diff --git a/pom.xml b/pom.xml
index ad1a899..f403098 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,10 +14,10 @@
4.0.0com.ibm.devops
- ibm-cloud-devops
- 1.1.7-SNAPSHOT
+ ibm-continuous-release
+ 1.1.0hpi
- IBM Cloud DevOps
+ IBM Continuous ReleaseThis plugin can be used to integrate your Jenkins pipelines and jobs with IBM DevOps Insights offering. The IBM DevOps Insights offering tracks your deployment risk based on the data that you publish to it. It provides Gates so that you can stop builds from getting deployed if the Gate policy is not met. The offering also provides analysis of your Git repo. For example, it can provide trends for large commits, error prone files, and team dynamics. Very soon, the offering will provide more trends, e.g., Deploy Frequency, Build Frequency, Unit Tests and Code Coverage and Function Verification Tests for builds that have deployed to production or other environments.https://wiki.jenkins-ci.org/display/JENKINS/IBM+Cloud+DevOps+Plugin
@@ -61,6 +61,7 @@
maven.jenkins-ci.orghttps://repo.jenkins-ci.org/snapshots/
+
@@ -72,29 +73,9 @@
- xunrongl
- Xunrong Li
- xunrongli@us.ibm.com
-
-
- aggarwav
- Vijay Aggarwal
- aggarwav@us.ibm.com
-
-
- imvijay2007
- Vijay Jegaselvan
- vjegase@us.ibm.com
-
-
- ejodet
- Eric Jodet
- eric_jodet@fr.ibm.com
-
-
- patjoy
- Patrick Joy
- patrick.joy1@ibm.com
+ aberk
+ Andy Berkebile
+ aberkeb1@us.ibm.com
@@ -105,6 +86,10 @@
+
+ Local repository
+ file://${basedir}/lib
+ repo.jenkins-ci.orghttps://repo.jenkins-ci.org/public/
@@ -112,10 +97,6 @@
-
- Local repository
- file://${basedir}/lib
- spring-snapshotsSpring Snapshots
@@ -144,6 +125,11 @@
httpcore4.4.5
+
+ org.jenkins-ci.plugins
+ unique-id
+ 2.1.3
+ org.apache.httpcomponentshttpmime
@@ -189,5 +175,59 @@
${powermock.version}test
+
+ uc-cloud-connect-java
+ cloud-connect-java
+ 1.0.920563
+ compile
+
+
+ org.jenkins-ci.plugins
+ cloudbees-folder
+ 6.0.4
+
+
+ org.apache.commons
+ commons-lang3
+ 3.1
+
+
+ io.socket
+ socket.io-client
+ 0.8.3
+ compile
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-job
+ 2.11.2
+
+
+ org.jenkins-ci.plugins
+ git
+ 3.6.0
+
+
+ org.jenkins-ci.plugins.workflow
+ workflow-api
+ 2.22
+
+
+ org.jenkins-ci.plugins
+ cloudbees-folder
+ 6.0.0
+
+
+ org.acegisecurity
+ acegi-security
+ 1.0.7
+ provided
+
+
+ com.ibm.devops
+ ibm-cloud-devops
+ 1.1.18
+ true
+
-
+
\ No newline at end of file
diff --git a/screenshots/PostBuild-WebHookNotification.png b/screenshots/PostBuild-WebHookNotification.png
deleted file mode 100644
index ff9eeff..0000000
Binary files a/screenshots/PostBuild-WebHookNotification.png and /dev/null differ
diff --git a/screenshots/Upload-Test-Result.png b/screenshots/Upload-Test-Result.png
deleted file mode 100644
index 5eae73e..0000000
Binary files a/screenshots/Upload-Test-Result.png and /dev/null differ
diff --git a/src/main/java/com/ibm/devops/connect/CRPipeline/ContinuousReleaseProperties.java b/src/main/java/com/ibm/devops/connect/CRPipeline/ContinuousReleaseProperties.java
new file mode 100644
index 0000000..ff530e1
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CRPipeline/ContinuousReleaseProperties.java
@@ -0,0 +1,166 @@
+/**
+ * (c) Copyright IBM Corporation 2018.
+ * This is licensed under the following license.
+ * The Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+ */
+
+package com.ibm.devops.connect.CRPipeline;
+
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import hudson.AbortException;
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.FilePath;
+import hudson.FilePath.FileCallable;
+import hudson.Launcher;
+import hudson.model.AbstractProject;
+import hudson.model.Descriptor.FormException;
+import hudson.remoting.VirtualChannel;
+import hudson.model.Hudson;
+import hudson.model.Result;
+import hudson.model.Run;
+import hudson.model.TaskListener;
+import hudson.tasks.Builder;
+import hudson.tasks.BuildStepDescriptor;
+import hudson.util.Secret;
+
+import jenkins.tasks.SimpleBuildStep;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+
+import net.sf.json.JSONObject;
+
+import org.jenkinsci.remoting.RoleChecker;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.StaplerRequest;
+
+import java.util.Map;
+
+import com.ibm.devops.connect.Status.CrAction;
+
+public class ContinuousReleaseProperties extends Builder implements SimpleBuildStep {
+
+ private Map properties;
+
+ /**
+ * Constructor used for data-binding fields from the corresponding
+ * config.jelly
+ *
+ * @param siteName
+ * The profile name of the UrbanDeploy site
+ * @param component
+ * The object holding the Create Version Block structure
+ * @param deploy
+ * The object holding the Deploy Block structure
+ */
+ @DataBoundConstructor
+ public ContinuousReleaseProperties(
+ Map properties) {
+ this.properties = properties;
+ }
+
+ /*
+ * Accessors and mutators required for data-binding access
+ */
+
+ public Map getProperties() {
+ return this.properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param build
+ * @param launcher
+ * @param listener
+ * @return A boolean to represent if the build can continue
+ * @throws InterruptedException
+ * @throws java.io.IOException
+ * {@inheritDoc}
+ * @see hudson.tasks.BuildStep#perform(hudson.model.Build, hudson.Launcher,
+ * hudson.model.TaskListener)
+ */
+ @Override
+ public void perform(final Run, ?> build, FilePath workspace, Launcher launcher, final TaskListener listener)
+ throws AbortException, InterruptedException, IOException {
+ CrAction action = build.getAction(CrAction.class);
+
+ if(action == null) {
+ action = new CrAction();
+ build.addAction(action);
+ }
+
+ if (properties != null) {
+ action.updateCrProperties(properties);
+ }
+ }
+
+ /**
+ * This class holds the metadata for the Publisher and allows it's data
+ * fields to persist
+ *
+ */
+ @Extension
+ public static class ContinuousReleasePropertiesDescriptor extends BuildStepDescriptor {
+
+ public ContinuousReleasePropertiesDescriptor() {
+ load();
+ }
+
+ /**
+ * Return the location of the help document for this builder.
+ *
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ * @see hudson.model.Descriptor#getHelpFile()
+ */
+ @Override
+ public String getHelpFile() {
+ return "/plugin/ibm-ucdeploy-build-steps/publish.html";
+ }
+
+ /**
+ * Bind data fields to user defined values {@inheritDoc}
+ *
+ * @param req
+ * {@inheritDoc}
+ * @param formData
+ * {@inheritDoc}
+ * @return {@inheritDoc}
+ * @see hudson.model.Descriptor#configure(org.kohsuke.stapler.StaplerRequest)
+ */
+ @Override
+ public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
+ req.bindJSON(this, formData);
+ save();
+ return super.configure(req, formData);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String getDisplayName() {
+ return "Pass Properties to Continuous Release Version";
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param jobType
+ * {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean isApplicable(Class extends AbstractProject> jobType) {
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/CloudBuildStepListener.java b/src/main/java/com/ibm/devops/connect/CloudBuildStepListener.java
new file mode 100644
index 0000000..fb51e25
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudBuildStepListener.java
@@ -0,0 +1,90 @@
+/*
+
+
+ Copyright 2016, 2017 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect;
+
+import java.util.Map;
+
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.model.*;
+import hudson.model.BuildStepListener;
+import hudson.tasks.BuildStep;
+import hudson.model.AbstractBuild;
+import hudson.tasks.Builder;
+import hudson.model.Result;
+
+import jenkins.model.Jenkins;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashSet;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.sf.json.JSONObject;
+import net.sf.json.JSONArray;
+
+import com.ibm.devops.connect.CloudCause.JobStatus;
+import com.ibm.devops.connect.Status.JenkinsJobStatus;
+
+@Extension
+public class CloudBuildStepListener extends BuildStepListener {
+ public static final Logger log = LoggerFactory.getLogger(CloudBuildStepListener.class);
+
+ public void finished(AbstractBuild build, BuildStep bs, BuildListener listener, boolean canContinue) {
+
+ CloudCause cloudCause = getCloudCause(build);
+ if (cloudCause == null) {
+ cloudCause = new CloudCause();
+ }
+ JenkinsJobStatus status = new JenkinsJobStatus(build, cloudCause, bs, listener, false, !canContinue);
+ JSONObject statusUpdate = status.generate();
+ CloudPublisher cloudPublisher = new CloudPublisher();
+ cloudPublisher.uploadJobStatus(statusUpdate);
+ }
+
+ public void started(AbstractBuild build, BuildStep bs, BuildListener listener) {
+ // We listen to jobs that are started by IBM Cloud only
+ if(this.shouldListen(build)) {
+ JenkinsJobStatus status = new JenkinsJobStatus(build, getCloudCause(build), bs, listener, true, false);
+ JSONObject statusUpdate = status.generate();
+ CloudPublisher cloudPublisher = new CloudPublisher();
+ cloudPublisher.uploadJobStatus(statusUpdate);
+ }
+ }
+
+ private boolean shouldListen(AbstractBuild build) {
+ if(getCloudCause(build) == null) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private CloudCause getCloudCause(AbstractBuild build) {
+ List causes = build.getCauses();
+
+ for(Cause cause : causes) {
+ if (cause instanceof CloudCause ) {
+ return (CloudCause)cause;
+ }
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/CloudCause.java b/src/main/java/com/ibm/devops/connect/CloudCause.java
new file mode 100644
index 0000000..7952d94
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudCause.java
@@ -0,0 +1,120 @@
+package com.ibm.devops.connect;
+
+import hudson.model.Cause;
+import hudson.model.Node;
+
+import java.util.List;
+import java.util.Set;
+import java.util.ArrayList;
+import net.sf.json.JSONObject;
+import net.sf.json.JSONArray;
+import com.ibm.devops.connect.Status.DRAData;
+import com.ibm.devops.connect.Status.SourceData;
+
+/**
+* This is the cause object that is attached to a build if it is started by the IBM Cloud.
+*/
+public class CloudCause extends Cause {
+
+ public enum JobStatus {
+ unstarted, started, success, failure
+ }
+
+ private String workId;
+ private JSONObject returnProps;
+ private List steps = new ArrayList();
+
+ private SourceData sourceData;
+ private DRAData draData;
+
+ private Boolean createdFromCR = false;
+
+ // private ConnectSocket socket;
+
+ public CloudCause(String workId, JSONObject returnProps) {
+ this.workId = workId;
+ this.returnProps = returnProps;
+ this.createdFromCR = true;
+ }
+
+ public CloudCause() {
+ this.createdFromCR = false;
+ }
+
+ @Override
+ public String getShortDescription() {
+ return "Started due to a request from IBM Continuous Release. Work Id: " + this.workId;
+ }
+
+ public void addStep(String name, String status, String message, boolean isFatal) {
+ JSONObject obj = new JSONObject();
+ obj.put("name", name);
+ obj.put("status", status);
+ obj.put("message", message);
+ obj.put("isFatal", isFatal);
+ steps.add(obj);
+ }
+
+ public void setSourceData(SourceData sourceData) {
+ this.sourceData = sourceData;
+ }
+
+ public SourceData getSourceData() {
+ return this.sourceData;
+ }
+
+ public void setDRAData(DRAData draData) {
+ this.draData = draData;
+ }
+
+ public DRAData getDRAData() {
+ return this.draData;
+ }
+
+ public JSONObject getSourceDataJson() {
+ if(this.sourceData == null) {
+ return new JSONObject();
+ } else {
+ return sourceData.toJson();
+ }
+ }
+
+ public JSONObject getDRADataJson() {
+ if(this.draData == null) {
+ return new JSONObject();
+ } else {
+ return draData.toJson();
+ }
+ }
+
+ public void updateLastStep(String name, String status, String message, boolean isFatal) {
+ if (steps.size() == 0) {
+ addStep(name, status, message, isFatal);
+ } else {
+ JSONObject obj = steps.get(steps.size() - 1);
+ if(name != null) {
+ obj.put("name", name);
+ }
+ obj.put("status", status);
+ obj.put("message", message);
+ obj.put("isFatal", isFatal);
+ }
+ }
+
+ public Boolean isCreatedByCR() {
+ return this.createdFromCR;
+ }
+
+ public JSONObject getReturnProps() {
+ return returnProps;
+ }
+
+ public JSONArray getStepsArray() {
+ JSONArray result = new JSONArray();
+ for (JSONObject obj : steps) {
+ result.add(obj);
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/CloudFlowExecutionListener.java b/src/main/java/com/ibm/devops/connect/CloudFlowExecutionListener.java
new file mode 100644
index 0000000..000d7fa
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudFlowExecutionListener.java
@@ -0,0 +1,70 @@
+/*
+
+
+ Copyright 2016, 2017 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect;
+
+import java.util.Map;
+
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.model.*;
+import hudson.model.BuildStepListener;
+import hudson.tasks.BuildStep;
+import hudson.model.AbstractBuild;
+import hudson.tasks.Builder;
+import hudson.model.Result;
+
+import jenkins.model.Jenkins;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashSet;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.sf.json.JSONObject;
+import net.sf.json.JSONArray;
+
+import com.ibm.devops.connect.CloudCause.JobStatus;
+
+import org.jenkinsci.plugins.workflow.flow.FlowExecutionListener;
+import org.jenkinsci.plugins.workflow.flow.FlowExecution;
+import org.jenkinsci.plugins.workflow.steps.StepExecution;
+import org.jenkinsci.plugins.workflow.graph.FlowNode;
+import org.jenkinsci.plugins.workflow.job.WorkflowRun;
+
+import java.io.IOException;
+
+@Extension
+public class CloudFlowExecutionListener extends FlowExecutionListener {
+ public static final Logger log = LoggerFactory.getLogger(CloudFlowExecutionListener.class);
+
+ @Override
+ public void onRunning(FlowExecution execution) {
+
+ }
+
+ @Override
+ public void onResumed(FlowExecution execution) {
+
+ }
+
+ @Override
+ public void onCompleted(FlowExecution execution) {
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/CloudGraphListener.java b/src/main/java/com/ibm/devops/connect/CloudGraphListener.java
new file mode 100644
index 0000000..536f57e
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudGraphListener.java
@@ -0,0 +1,101 @@
+/*
+
+
+ Copyright 2016, 2017 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect;
+
+import java.util.Map;
+
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.model.*;
+import hudson.model.BuildStepListener;
+import hudson.tasks.BuildStep;
+import hudson.model.AbstractBuild;
+import hudson.tasks.Builder;
+import hudson.model.Result;
+
+import jenkins.model.Jenkins;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashSet;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.sf.json.JSONObject;
+import net.sf.json.JSONArray;
+
+import com.ibm.devops.connect.CloudCause.JobStatus;
+
+import org.jenkinsci.plugins.workflow.flow.GraphListener;
+import org.jenkinsci.plugins.workflow.flow.FlowExecution;
+import org.jenkinsci.plugins.workflow.steps.StepExecution;
+import org.jenkinsci.plugins.workflow.graph.FlowNode;
+import org.jenkinsci.plugins.workflow.job.WorkflowRun;
+import org.jenkinsci.plugins.workflow.support.actions.PauseAction;
+
+import com.ibm.devops.connect.Status.JenkinsPipelineStatus;
+
+import java.io.IOException;
+
+@Extension
+public class CloudGraphListener implements GraphListener {
+ public static final Logger log = LoggerFactory.getLogger(CloudGraphListener.class);
+
+ public void onNewHead(FlowNode node) {
+ FlowExecution execution = node.getExecution();
+
+ WorkflowRun workflowRun = null;
+
+ try {
+ if (execution.getOwner().getExecutable() instanceof WorkflowRun) {
+ workflowRun = (WorkflowRun)(execution.getOwner().getExecutable());
+ }
+ } catch (IOException e) {
+ log.error("HIT THE IOEXCEPTION: " + e);
+ return;
+ }
+
+ CloudCause cloudCause = getCloudCause(workflowRun);
+ if (cloudCause == null) {
+ cloudCause = new CloudCause();
+ }
+
+ boolean isStartNode = node.getClass().getName().equals("org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode");
+ boolean isEndNode = node.getClass().getName().equals("org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode");
+ boolean isPauseNode = PauseAction.isPaused(node);
+
+ if(isStartNode || isEndNode || isPauseNode) {
+ JenkinsPipelineStatus status = new JenkinsPipelineStatus(workflowRun, cloudCause, node, null, isStartNode, isPauseNode);
+ JSONObject statusUpdate = status.generate();
+ CloudPublisher cloudPublisher = new CloudPublisher();
+ cloudPublisher.uploadJobStatus(statusUpdate);
+ }
+ }
+
+ private CloudCause getCloudCause(WorkflowRun workflowRun) {
+ List causes = workflowRun.getCauses();
+
+ for(Cause cause : causes) {
+ if (cause instanceof CloudCause ) {
+ return (CloudCause)cause;
+ }
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/CloudItemListener.java b/src/main/java/com/ibm/devops/connect/CloudItemListener.java
new file mode 100644
index 0000000..9c9a2a6
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudItemListener.java
@@ -0,0 +1,90 @@
+/*
+
+
+ Copyright 2016, 2017 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect;
+
+
+import hudson.EnvVars;
+import hudson.Extension;
+import hudson.model.*;
+import hudson.model.listeners.ItemListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.sf.json.JSONObject;
+
+import com.cloudbees.hudson.plugins.folder.Folder;
+
+@Extension
+public class CloudItemListener extends ItemListener {
+ public static final Logger log = LoggerFactory.getLogger(CloudItemListener.class);
+ private String logPrefix= "[IBM Cloud DevOps] CloudItemListener#";
+
+ public CloudItemListener(){
+ logPrefix= logPrefix + "CloudItemListener ";
+ log.info(logPrefix + "CloudItemListener started...");
+ }
+
+ @Override
+ public void onCreated(Item item) {
+ handleEvent(item, "CREATED");
+ }
+
+ @Override
+ public void onDeleted(Item item) {
+ handleEvent(item, "DELETED");
+ }
+
+ @Override
+ public void onUpdated(Item item) {
+ handleEvent(item, "UPDATED");
+ }
+
+ private void handleEvent(Item item, String phase) {
+ CloudSocketComponent socket = new ConnectComputerListener().getCloudSocketInstance();
+ if(socket.connected()) {
+ if( !(item instanceof Folder) ) {
+ JenkinsJob jenkinsJob= new JenkinsJob(item);
+ log.info(ToStringBuilder.reflectionToString(jenkinsJob.toJson()) + " was " + phase);
+ CloudPublisher cloudPublisher = new CloudPublisher();
+ cloudPublisher.uploadJobInfo(jenkinsJob.toJson());
+ }
+ }
+
+ // we'll handle the updates to the sync app here
+ }
+
+ public List buildJobsList() {
+ log.info(logPrefix + "Building the list of Jenkins jobs...");
+ List allProjects= JenkinsServer.getAllItems();
+ List allJobs = new ArrayList();
+
+ CloudPublisher cloudPublisher = new CloudPublisher();
+ for (Item anItem : allProjects) {
+ if( !(anItem instanceof Folder) ) {
+ JenkinsJob jenkinsJob= new JenkinsJob(anItem);
+ allJobs.add(jenkinsJob.toJson());
+
+ cloudPublisher.uploadJobInfo(jenkinsJob.toJson());
+ }
+ }
+ return allJobs;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/CloudPublisher.java b/src/main/java/com/ibm/devops/connect/CloudPublisher.java
new file mode 100644
index 0000000..3e4cbe1
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudPublisher.java
@@ -0,0 +1,442 @@
+/*
+
+
+ Copyright 2016, 2017 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ibm.devops.connect.DevOpsGlobalConfiguration;
+
+import net.sf.json.JSONObject;
+import net.sf.json.JSONArray;
+
+import com.google.gson.*;
+import jenkins.model.Jenkins;
+import jenkins.tasks.SimpleBuildStep;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.kohsuke.stapler.*;
+import javax.xml.bind.DatatypeConverter;
+
+import javax.annotation.Nonnull;
+import javax.servlet.ServletException;
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.TimeZone;
+import java.net.URLEncoder;
+
+import org.apache.commons.codec.binary.Base64;
+
+import com.ibm.devops.connect.Endpoints.EndpointManager;
+
+import org.jenkinsci.plugins.uniqueid.IdStore;
+
+import hudson.tasks.BuildStepDescriptor;
+import hudson.tasks.BuildStepMonitor;
+
+public class CloudPublisher {
+ public static final Logger log = LoggerFactory.getLogger(CloudPublisher.class);
+ private String logPrefix= "[IBM Cloud DevOps] CloudPublisher#";
+
+ private final String JENKINS_JOB_ENDPOINT_URL = "api/v1/jenkins/jobs";
+ private final String JENKINS_JOB_STATUS_ENDPOINT_URL = "api/v1/jenkins/jobStatus";
+ private final String INTEGRATIONS_ENDPOINT_URL = "api/v1/integrations";
+ private final String INTEGRATION_ENDPOINT_URL = "api/v1/integrations/{integration_id}";
+
+ private static String BUILD_API_URL = "/organizations/{org_name}/toolchainids/{toolchain_id}/buildartifacts/{build_artifact}/builds";
+ private final static String CONTENT_TYPE_JSON = "application/json";
+ private final static String CONTENT_TYPE_XML = "application/xml";
+
+ // form fields from UI
+ private String applicationName;
+ private String orgName;
+ private String credentialsId;
+ private String toolchainName;
+
+ private String dlmsUrl;
+ private PrintStream printStream;
+ private File root;
+ private static String bluemixToken;
+ private static String preCredentials;
+
+ // fields to support jenkins pipeline
+ private String result;
+ private String gitRepo;
+ private String gitBranch;
+ private String gitCommit;
+ private String username;
+ private String password;
+ // optional customized build number
+ private String buildNumber;
+
+ public CloudPublisher() {
+ }
+
+ private String getSyncApiUrl() {
+ EndpointManager em = new EndpointManager();
+ return em.getSyncApiEndpoint();
+ }
+
+ private String getSyncStoreUrl() {
+ EndpointManager em = new EndpointManager();
+ return em.getSyncStoreEndpoint();
+ }
+
+ /**
+ * Upload the build information to Sync API - API V1.
+ */
+ public boolean uploadJobInfo(JSONObject jobJson) {
+ String url = this.getSyncApiUrl() + JENKINS_JOB_ENDPOINT_URL;
+
+ JSONArray payload = new JSONArray();
+ payload.add(jobJson);
+
+ return postToSyncAPI(url, payload.toString());
+ }
+
+ public boolean uploadJobStatus(JSONObject jobStatus) {
+
+ String url = this.getSyncApiUrl() + JENKINS_JOB_STATUS_ENDPOINT_URL;
+ return postToSyncAPI(url, jobStatus.toString());
+ }
+
+ private boolean postToSyncAPI(String url, String payload) {
+ String localLogPrefix= logPrefix + "uploadJobInfo ";
+
+ String resStr = "";
+
+ try {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+
+ JenkinsIntegrationId jenkinsIntegrationId = new JenkinsIntegrationId();
+ String jenkinsId = jenkinsIntegrationId.getIntegrationId();
+
+ HttpPost postMethod = new HttpPost(url);
+ // postMethod = addProxyInformation(postMethod);
+ postMethod.setHeader("sync_token", Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncToken());
+ postMethod.setHeader("sync_id", Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId());
+ postMethod.setHeader("instance_type", "JENKINS");
+ postMethod.setHeader("instance_id", jenkinsId);
+ postMethod.setHeader("integration_id", jenkinsId);
+ postMethod.setHeader("Content-Type", "application/json");
+
+ StringEntity data = new StringEntity(payload);
+ postMethod.setEntity(data);
+
+ CloseableHttpResponse response = httpClient.execute(postMethod);
+
+ resStr = EntityUtils.toString(response.getEntity());
+ if (response.getStatusLine().toString().contains("200")) {
+ // get 200 response
+ log.info(localLogPrefix + "Upload Job Information successfully");
+ return true;
+
+ } else {
+ // if gets error status
+ log.error(localLogPrefix + "Error: Failed to upload Job, response status " + response.getStatusLine());
+ }
+ } catch (JsonSyntaxException e) {
+ log.error(localLogPrefix + "Invalid Json response, response: " + resStr);
+ } catch (IllegalStateException e) {
+ // will be triggered when 403 Forbidden
+ try {
+ log.error(localLogPrefix + "Please check if you have the access to " + URLEncoder.encode(this.orgName, "UTF-8") + " org");
+ } catch (UnsupportedEncodingException e1) {
+ e1.printStackTrace();
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (ClientProtocolException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean doesIntegrationExist() {
+ String localLogPrefix = logPrefix + "doesIntegrationExist ";
+ String resStr = "";
+ try {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+
+ JenkinsIntegrationId jenkinsIntegrationId = new JenkinsIntegrationId();
+ String jenkinsId = jenkinsIntegrationId.getIntegrationId();
+
+ String url = this.getSyncStoreUrl() + INTEGRATION_ENDPOINT_URL.replace("{integration_id}", jenkinsId);
+
+ HttpGet getMethod = new HttpGet(url);
+ // postMethod = addProxyInformation(postMethod);
+ getMethod.setHeader("Content-Type", "application/json");
+
+ String authEncoding = DatatypeConverter.printBase64Binary((Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId() + ":" + Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncToken()).getBytes("UTF-8"));
+ getMethod.setHeader("Authorization", "Basic " + authEncoding);
+
+ CloseableHttpResponse response = httpClient.execute(getMethod);
+
+ resStr = EntityUtils.toString(response.getEntity());
+ if (response.getStatusLine().toString().contains("200") || response.getStatusLine().toString().contains("201")) {
+ // get 200 response
+ log.info(localLogPrefix + "Integration was retrieved");
+
+ JSONObject jsonBody = JSONObject.fromObject(resStr);
+
+ String serverUrl = Jenkins.getInstance().getRootUrl();
+
+ if(!serverUrl.equals(jsonBody.get("serverUrl"))) {
+ log.info(localLogPrefix + "Must update server url on integration...");
+ updateIntegrationServerUrl(jsonBody, serverUrl);
+ }
+
+ return true;
+
+ } else {
+
+ log.info(localLogPrefix + "No Integration Retrieved");
+
+ return false;
+ }
+ } catch (JsonSyntaxException e) {
+ log.error(localLogPrefix + "Invalid Json response, response: " + resStr);
+ } catch (IllegalStateException e) {
+ // will be triggered when 403 Forbidden
+ try {
+ log.info(localLogPrefix + "Please check if you have the access to " + URLEncoder.encode(this.orgName, "UTF-8") + " org");
+ } catch (UnsupportedEncodingException e1) {
+ e1.printStackTrace();
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (ClientProtocolException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean createIntegration() {
+ String localLogPrefix= logPrefix + "createIntegration ";
+ String resStr = "";
+
+ JenkinsIntegrationId jenkinsIntegrationId = new JenkinsIntegrationId();
+ String jenkinsId = jenkinsIntegrationId.getIntegrationId();
+
+ try {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+
+ String url = this.getSyncStoreUrl() + INTEGRATIONS_ENDPOINT_URL;
+
+ JSONObject newIntegration = new JSONObject();
+
+ newIntegration.put("name", "Jenkins Plugin Integration - " + jenkinsId);
+ newIntegration.put("syncId", Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId());
+ newIntegration.put("id", jenkinsId);
+ newIntegration.put("dateCreated", System.currentTimeMillis());
+ newIntegration.put("docType", "integration");
+ newIntegration.put("serverUrl", Jenkins.getInstance().getRootUrl());
+ newIntegration.put("type", "JENKINS");
+
+ HttpPost postMethod = new HttpPost(url);
+ // postMethod = addProxyInformation(postMethod);
+ postMethod.setHeader("Content-Type", "application/json");
+ String authEncoding = DatatypeConverter.printBase64Binary((Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId() + ":" + Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncToken()).getBytes("UTF-8"));
+ postMethod.setHeader("Authorization", "Basic " + authEncoding);
+
+ postMethod.setHeader("syncId", Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId());
+
+ StringEntity data = new StringEntity(newIntegration.toString());
+ postMethod.setEntity(data);
+
+ CloseableHttpResponse response = httpClient.execute(postMethod);
+
+ resStr = EntityUtils.toString(response.getEntity());
+ if (response.getStatusLine().toString().contains("200") || response.getStatusLine().toString().contains("201")) {
+ // get 200 response
+ log.info("===================================================");
+ log.info(localLogPrefix + "Created integration successfully");
+ return true;
+
+ } else {
+ // if gets error status
+ log.error(localLogPrefix + "Error: Failed to create integration, response status " + response.getStatusLine());
+ }
+ } catch (JsonSyntaxException e) {
+ log.error(localLogPrefix + "Invalid Json response, response: " + resStr);
+ } catch (IllegalStateException e) {
+ // will be triggered when 403 Forbidden
+ try {
+ log.error(localLogPrefix + "Please check if you have the access to " + URLEncoder.encode(this.orgName, "UTF-8") + " org");
+ } catch (UnsupportedEncodingException e1) {
+ e1.printStackTrace();
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (ClientProtocolException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ private boolean updateIntegrationServerUrl(JSONObject payload, String newServerUrl) {
+ String localLogPrefix= logPrefix + "updateIntegrationServerUrl ";
+
+ payload.put("serverUrl", newServerUrl);
+
+ return (updateIntegration(payload));
+ }
+
+ private boolean updateIntegration(JSONObject payload) {
+ String localLogPrefix= logPrefix + "updateIntegrationServerUrl ";
+
+ try {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+
+ String url = this.getSyncStoreUrl() + INTEGRATIONS_ENDPOINT_URL;
+
+ HttpPost putMethod = new HttpPost(url);
+ // putMethod = addProxyInformation(putMethod);
+ putMethod.setHeader("Content-Type", "application/json");
+ String authEncoding = DatatypeConverter.printBase64Binary((Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId() + ":" + Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncToken()).getBytes("UTF-8"));
+ putMethod.setHeader("Authorization", "Basic " + authEncoding);
+
+ putMethod.setHeader("syncId", Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId());
+
+ StringEntity data = new StringEntity(payload.toString());
+ putMethod.setEntity(data);
+
+ CloseableHttpResponse response = httpClient.execute(putMethod);
+
+ if (response.getStatusLine().toString().contains("200") || response.getStatusLine().toString().contains("201")) {
+ log.info(localLogPrefix + "Upated integration successfully");
+ return true;
+
+ } else {
+ // if gets error status
+ log.error(localLogPrefix + "Error: Failed to update integration, response status " + response.getStatusLine());
+ }
+ } catch (JsonSyntaxException e) {
+ log.error(localLogPrefix + "Invalid Json response, response");
+ } catch (IllegalStateException e) {
+ // will be triggered when 403 Forbidden
+ try {
+ log.error(localLogPrefix + "Please check if you have the access to " + URLEncoder.encode(this.orgName, "UTF-8") + " org");
+ } catch (UnsupportedEncodingException e1) {
+ e1.printStackTrace();
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (ClientProtocolException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ public boolean doesOtherIntegrationExist() {
+ String localLogPrefix= logPrefix + "doesOtherIntegrationExist ";
+
+ String resStr = "";
+
+ try {
+ CloseableHttpClient httpClient = HttpClients.createDefault();
+
+ JenkinsIntegrationId jenkinsIntegrationIdGenerator = new JenkinsIntegrationId();
+ String jenkinsIntegrationId = jenkinsIntegrationIdGenerator.getIntegrationId();
+
+ String url = this.getSyncStoreUrl() + INTEGRATIONS_ENDPOINT_URL;
+
+ HttpGet getMethod = new HttpGet(url);
+ // postMethod = addProxyInformation(postMethod);
+ getMethod.setHeader("Content-Type", "application/json");
+
+ String authEncoding = DatatypeConverter.printBase64Binary((Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId() + ":" + Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncToken()).getBytes("UTF-8"));
+ getMethod.setHeader("Authorization", "Basic " + authEncoding);
+
+ CloseableHttpResponse response = httpClient.execute(getMethod);
+
+ resStr = EntityUtils.toString(response.getEntity());
+ if (response.getStatusLine().toString().contains("200") || response.getStatusLine().toString().contains("201")) {
+
+ JSONArray jsonBody = JSONArray.fromObject(resStr);
+
+ boolean updatedOldIntegration = false;
+ boolean integrationFound = false;
+
+ for (int i = 0; i < jsonBody.size(); i++) {
+ JSONObject integrationObj = jsonBody.getJSONObject(i);
+ updatedOldIntegration = updateLegacyIntegrationIfNecessary(integrationObj);
+ if(integrationObj.get("id").equals(jenkinsIntegrationId)) {
+ integrationFound = true;
+ }
+ }
+
+ if(!updatedOldIntegration && jsonBody.size() > 0 && !integrationFound) {
+ return true;
+ }
+ }
+ } catch (JsonSyntaxException e) {
+ log.error(localLogPrefix + "Invalid Json response, response: " + resStr);
+ } catch (IllegalStateException e) {
+ // will be triggered when 403 Forbidden
+ try {
+ log.info(localLogPrefix + "Please check if you have the access to " + URLEncoder.encode(this.orgName, "UTF-8") + " org");
+ } catch (UnsupportedEncodingException e1) {
+ e1.printStackTrace();
+ }
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (ClientProtocolException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ /*
+ * currently, the integration ID is the sync ID concatenated with an underscore and the Jenkins Server ID. The original integration ID was
+ * just the Jenkins Server ID. If we find the Jenkins Server Id, we update that record with the proper Integration Id
+ */
+
+ private boolean updateLegacyIntegrationIfNecessary(JSONObject integrationObj) {
+ String jenkinsId;
+ if (IdStore.getId(Jenkins.getInstance()) != null) {
+ jenkinsId = IdStore.getId(Jenkins.getInstance());
+ } else {
+ IdStore.makeId(Jenkins.getInstance());
+ jenkinsId = IdStore.getId(Jenkins.getInstance());
+ }
+
+ if(integrationObj.get("id").equals(jenkinsId)) {
+ JenkinsIntegrationId jenkinsIntegrationId = new JenkinsIntegrationId();
+ integrationObj.put("id", jenkinsIntegrationId.getIntegrationId());
+ return updateIntegration(integrationObj);
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/com/ibm/devops/connect/CloudRunListener.java b/src/main/java/com/ibm/devops/connect/CloudRunListener.java
new file mode 100644
index 0000000..f5b7ee5
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudRunListener.java
@@ -0,0 +1,76 @@
+/*
+
+
+ Copyright 2018 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+*/
+
+package com.ibm.devops.connect;
+
+import hudson.Extension;
+import hudson.model.listeners.RunListener;
+import hudson.model.TaskListener;
+import hudson.model.Cause;
+
+import org.jenkinsci.plugins.workflow.job.WorkflowRun;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.sf.json.JSONObject;
+import net.sf.json.JSONArray;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashSet;
+
+import com.ibm.devops.connect.CloudCause.JobStatus;
+import com.ibm.devops.connect.Status.JenkinsPipelineStatus;
+
+@Extension
+public class CloudRunListener extends RunListener {
+ public static final Logger log = LoggerFactory.getLogger(CloudRunListener.class);
+
+ @Override
+ public void onStarted(WorkflowRun workflowRun, TaskListener listener) {
+ // http://javadoc.jenkins.io/plugin/workflow-job/org/jenkinsci/plugins/workflow/job/WorkflowRun.html
+ CloudCause cloudCause = getCloudCause(workflowRun);
+ if (cloudCause == null) {
+ cloudCause = new CloudCause();
+ }
+ JenkinsPipelineStatus status = new JenkinsPipelineStatus(workflowRun, cloudCause, null, listener, true, false);
+ JSONObject statusUpdate = status.generate();
+ CloudPublisher cloudPublisher = new CloudPublisher();
+ cloudPublisher.uploadJobStatus(statusUpdate);
+ }
+
+ @Override
+ public void onCompleted(WorkflowRun workflowRun, TaskListener listener) {
+ CloudCause cloudCause = getCloudCause(workflowRun);
+ if (cloudCause == null) {
+ cloudCause = new CloudCause();
+ }
+ JenkinsPipelineStatus status = new JenkinsPipelineStatus(workflowRun, cloudCause, null, listener, false, false);
+ JSONObject statusUpdate = status.generate();
+ CloudPublisher cloudPublisher = new CloudPublisher();
+ cloudPublisher.uploadJobStatus(statusUpdate);
+ }
+
+ private CloudCause getCloudCause(WorkflowRun workflowRun) {
+ List causes = workflowRun.getCauses();
+
+ for(Cause cause : causes) {
+ if (cause instanceof CloudCause ) {
+ return (CloudCause)cause;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/com/ibm/devops/connect/CloudSocketComponent.java b/src/main/java/com/ibm/devops/connect/CloudSocketComponent.java
new file mode 100644
index 0000000..ac381cb
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudSocketComponent.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2017. All Rights Reserved.
+ *
+ * Note to U.S. Government Users Restricted Rights: Use,
+ * duplication or disclosure restricted by GSA ADP Schedule
+ * Contract with IBM Corp.
+ *******************************************************************************/
+package com.ibm.devops.connect;
+
+import java.net.URI;
+import java.util.Properties;
+
+import jenkins.model.Jenkins;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ibm.devops.connect.DevOpsGlobalConfiguration;
+
+import com.ibm.cloud.urbancode.connect.client.ConnectSocket;
+import com.ibm.cloud.urbancode.connect.client.Listeners;
+import com.ibm.devops.connect.OnConnectListener;
+
+import com.ibm.devops.connect.CloudPublisher;
+
+import io.socket.client.Socket;
+
+public class CloudSocketComponent {
+
+ public static final Logger log = LoggerFactory.getLogger(CloudSocketComponent.class);
+ private String logPrefix= "[IBM Cloud DevOps] CloudSocketComponent#";
+
+ final private IWorkListener workListener;
+ final private String cloudUrl;
+ private ConnectSocket socket;
+
+ private static boolean otherIntegrationExists = false;
+
+ public CloudSocketComponent(IWorkListener workListener, String cloudUrl) {
+ this.workListener = workListener;
+ this.cloudUrl = cloudUrl;
+ }
+
+ public boolean isRegistered() {
+ return StringUtils.isNotBlank(getSyncToken());
+ }
+
+ public String getSyncId() {
+ return Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId();
+ }
+
+ public String getSyncToken() {
+ return Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncToken();
+ }
+
+ public void connectToCloudServices() throws Exception {
+ logPrefix= logPrefix + "connectToCloudServices ";
+ String syncId = getSyncId();
+ String syncToken = getSyncToken();
+ if (StringUtils.isBlank(syncId) || StringUtils.isBlank(syncToken)) {
+ log.info(logPrefix + "Not connecting to the cloud. IBM Bluemix DevOps Connect not registered yet.");
+ return;
+ }
+
+ CloudPublisher cloudPublisher = new CloudPublisher();
+
+ boolean shouldConnect = true;
+ // Does integration exist
+ if(!cloudPublisher.doesIntegrationExist()) {
+ // Does another integration exist
+ if(cloudPublisher.doesOtherIntegrationExist()) {
+ log.warn(logPrefix + "These credentials have been used by another Jenkins Instance. Please generate another Sync Id and provide those credentials here.");
+ shouldConnect = false;
+ otherIntegrationExists = true;
+ } else {
+ // Create Integration
+ cloudPublisher.createIntegration();
+ }
+ } else {
+ otherIntegrationExists = false;
+ }
+
+ if(shouldConnect) {
+ URI uri = new URI(cloudUrl);
+ log.info(logPrefix + "Starting cloud endpoint " + syncId);
+ socket = ConnectSocket.builder()
+ .uri(uri)
+ .id(syncId)
+ .token(syncToken)
+ .onConnect(Listeners.chain(Listeners.chain(Listeners.INFO_LOGGING, Listeners.EMIT_GET_WORK), OnConnectListener.BUILD_JOBS_LIST))
+ .onDisconnect(Listeners.INFO_LOGGING)
+ .onWorkAvailable(Listeners.chain(Listeners.DEBUG_LOGGING, Listeners.EMIT_GET_WORK))
+ .onWork(workListener)
+ // .onWork(Listeners.chain(Listeners.INFO_LOGGING, workListener))
+ .onError(Listeners.ERROR_LOGGING)
+ .build();
+ socket.on(Socket.EVENT_CONNECT_ERROR, Listeners.ERROR_LOGGING);
+ socket.on(Socket.EVENT_CONNECT_TIMEOUT, Listeners.ERROR_LOGGING);
+ socket.on(Socket.EVENT_RECONNECT_ERROR, Listeners.ERROR_LOGGING);
+ socket.on(Socket.EVENT_RECONNECT_FAILED, Listeners.ERROR_LOGGING);
+ socket.on(Socket.EVENT_RECONNECT_ATTEMPT, Listeners.INFO_LOGGING);
+ // do not listen for Socket.EVENT_RECONNECT, we will make 2 get work requests
+
+ socket.connect();
+ }
+ }
+
+ // this does get called, but you may not see logging in the console. it will appear in the file.
+ public void disconnect() {
+ if (socket != null) {
+ try {
+ socket.disconnect();
+ log.info(logPrefix + "Disconnected from the cloud service");
+ }
+ catch (Exception e) {
+ log.error(logPrefix + "Error disconnecting the cloud service gracefully", e);
+ }
+ finally {
+ socket = null;
+ }
+ }
+ }
+
+ public boolean connected() {
+ if(socket == null) {
+ return false;
+ }
+ return socket.connected();
+ }
+
+ public String getCauseOfFailure() {
+ if (otherIntegrationExists) {
+ return "These credentials have been used by another Jenkins Instance. Please generate another Sync Id and provide those credentials here.";
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/com/ibm/devops/connect/CloudWorkListener.java b/src/main/java/com/ibm/devops/connect/CloudWorkListener.java
new file mode 100644
index 0000000..1025d78
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/CloudWorkListener.java
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2017. All Rights Reserved.
+ *
+ * Note to U.S. Government Users Restricted Rights: Use,
+ * duplication or disclosure restricted by GSA ADP Schedule
+ * Contract with IBM Corp.
+ *******************************************************************************/
+package com.ibm.devops.connect;
+
+import java.util.concurrent.TimeUnit;
+
+// import org.json.JSONArray;
+// import org.json.JSONException;
+// import org.json.JSONObject;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.ibm.cloud.urbancode.connect.client.ConnectSocket;
+
+import net.sf.json.*;
+import jenkins.model.Jenkins;
+import jenkins.model.ParameterizedJobMixIn;
+import hudson.model.AbstractProject;
+import hudson.model.AbstractItem;
+import hudson.model.Action;
+import hudson.model.ParametersAction;
+import hudson.model.CauseAction;
+import hudson.model.ParameterValue;
+import hudson.model.StringParameterValue;
+import hudson.model.BooleanParameterValue;
+import hudson.model.TextParameterValue;
+import hudson.model.PasswordParameterValue;
+import hudson.model.queue.QueueTaskFuture;
+import hudson.model.Queue;
+import hudson.model.Item;
+import hudson.model.ParameterDefinition;
+import hudson.model.ParametersDefinitionProperty;
+import hudson.model.JobProperty;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.lang.InterruptedException;
+
+import org.jenkinsci.plugins.workflow.job.WorkflowJob;
+
+import net.sf.json.JSONObject;
+
+import com.ibm.devops.connect.CloudCause.JobStatus;
+import com.ibm.devops.connect.SecuredAction.TriggerJob.TriggerJobParamObj;
+import com.ibm.devops.connect.SecuredAction.TriggerJob;
+
+import com.ibm.devops.connect.Status.JenkinsJobStatus;
+
+/*
+ * When Spring is applying the @Transactional annotation, it creates a proxy class which wraps your class.
+ * So when your bean is created in your application context, you are getting an object that is not of type
+ * WorkListener but some proxy class that implements the IWorkListener interface. So anywhere you want WorkListener
+ * injected, you must use IWorkListener.
+ */
+public class CloudWorkListener implements IWorkListener {
+ public static final Logger log = LoggerFactory.getLogger(CloudWorkListener.class);
+ private String logPrefix= "[IBM Cloud DevOps] CloudWorkListener#";
+
+ public CloudWorkListener() {
+
+ }
+
+ public enum WorkStatus {
+ success, failed, started
+ }
+
+ /* (non-Javadoc)
+ * @see com.ibm.cloud.urbancode.sync.IWorkListener#call(com.ibm.cloud.urbancode.connect.client.ConnectSocket, java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void call(ConnectSocket socket, String event, Object... args) {
+ TriggerJob triggerJob = new TriggerJob();
+
+ TriggerJobParamObj paramObj = triggerJob.new TriggerJobParamObj(socket, event, args);
+ triggerJob.runAsJenkinsUser(paramObj);
+ }
+
+ public void callSecured(ConnectSocket socket, String event, Object... args) {
+ log.info(logPrefix + " Received event from Connect Socket");
+
+ JSONArray incomingJobs = JSONArray.fromObject(args[0].toString());
+
+ for(int i=0; i < incomingJobs.size(); i++) {
+ JSONObject incomingJob = incomingJobs.getJSONObject(i);
+ // sample job creation request from a toolchain
+ if (incomingJob.has("jobType") && "new".equalsIgnoreCase(incomingJob.get("jobType").toString())) {
+ log.info(logPrefix + "Job creation request received.");
+ // delegating job creation to the Jenkins server
+ JenkinsServer.createJob(incomingJob);
+ }
+
+
+ if (incomingJob.has("fullName")) {
+ String fullName = incomingJob.get("fullName").toString();
+
+ Jenkins myJenkins = Jenkins.getInstance();
+
+ // Get item by name
+ Item item = myJenkins.getItem(fullName);
+
+ log.info("Item Found (1): " + item);
+
+ // If item is not retrieved, get by full name
+ if(item == null) {
+ item = myJenkins.getItemByFullName(fullName);
+ log.info("Item Found (2): " + item);
+ }
+
+ // If item is not retrieved, get by full name with escaped characters
+ if(item == null) {
+ item = myJenkins.getItemByFullName(escapeItemName(fullName));
+ log.info("Item Found (3): " + item);
+ }
+
+ System.out.println("HEEEEEEEYYYYYYY------------------------->>>>");
+ List parametersList = generateParamList(incomingJob, getParameterTypeMap(item));
+
+ JSONObject returnProps = new JSONObject();
+ if(incomingJob.has("returnProps")) {
+ returnProps = incomingJob.getJSONObject("returnProps");
+ }
+
+ CloudCause cloudCause = new CloudCause(incomingJob.get("id").toString(), returnProps);
+ Queue.Item queuedItem = null;
+ String errorMessage = null;
+
+ if(item instanceof AbstractProject) {
+ AbstractProject abstractProject = (AbstractProject)item;
+
+ queuedItem = ParameterizedJobMixIn.scheduleBuild2(abstractProject, 0, new ParametersAction(parametersList), new CauseAction(cloudCause));
+
+ if (queuedItem == null) {
+ errorMessage = "Could not start parameterized build.";
+ }
+ } else if (item instanceof WorkflowJob) {
+ WorkflowJob workflowJob = (WorkflowJob)item;
+
+ System.out.println("\n\n\t\t\t&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
+ System.out.println(parametersList);
+
+ QueueTaskFuture queuedTask = workflowJob.scheduleBuild2(0, new ParametersAction(parametersList), new CauseAction(cloudCause));
+
+ if (queuedTask == null) {
+ errorMessage = "Could not start pipeline build.";
+ }
+ } else if (item == null) {
+ errorMessage = "No Item Found";
+ log.warn(errorMessage);
+ } else {
+ errorMessage = "Unhandled job type found: " + item.getClass();
+ log.warn(errorMessage);
+ }
+
+ if( errorMessage != null ) {
+ JenkinsJobStatus erroredJobStatus = new JenkinsJobStatus(null, cloudCause, null, null, true, true);
+ JSONObject statusUpdate = erroredJobStatus.generateErrorStatus(errorMessage);
+ CloudPublisher cloudPublisher = new CloudPublisher();
+ cloudPublisher.uploadJobStatus(statusUpdate);
+ }
+
+ }
+
+ sendResult(socket, incomingJobs.getJSONObject(i).get("id").toString(), WorkStatus.started, "This work has been started");
+ }
+
+ }
+
+ private void sendResult(ConnectSocket socket, String id, WorkStatus status, String comment) {
+ JSONObject json = new JSONObject();
+ try {
+ json.put("id", id);
+ json.put("status", status.name());
+ json.put("description", comment);
+ }
+ catch (JSONException e) {
+ throw new RuntimeException("Error constructing work result JSON", e);
+ }
+ socket.emit("set_work_status", json.toString());
+ }
+
+ private List generateParamList (JSONObject incomingJob, Map typeMap) {
+ ArrayList result = new ArrayList();
+
+ System.out.println("000000000000000000000000000000000");
+ System.out.println(incomingJob.toString());
+ System.out.println(typeMap.toString());
+ System.out.println("000000000000000000000000000000000");
+
+ if(incomingJob.has("props")) {
+ JSONObject props = incomingJob.getJSONObject("props");
+ Iterator keys = props.keys();
+ while( keys.hasNext() ) {
+ String key = (String)keys.next();
+ Object value = props.get(key);
+ String type = typeMap.get(key);
+
+ ParameterValue paramValue;
+
+ System.out.println("->\t\t" + key);
+ System.out.println("->\t\t" + value);
+ System.out.println("->\t\t" + type);
+
+ if(type == null) {
+
+ } else if(type.equalsIgnoreCase("BooleanParameterDefinition")) {
+ if(props.get(key).getClass().equals(String.class)) {
+ Boolean p = Boolean.parseBoolean((String)props.get(key));
+ result.add(new BooleanParameterValue(key, p));
+ } else {
+ result.add(new BooleanParameterValue(key, (boolean)props.get(key)));
+ }
+ } else if(type.equalsIgnoreCase("PasswordParameterDefinition")) {
+ result.add(new PasswordParameterValue(key, props.get(key).toString()));
+ } else if(type.equalsIgnoreCase("TextParameterDefinition")) {
+ result.add(new TextParameterValue(key, props.get(key).toString()));
+ } else {
+ result.add(new StringParameterValue(key, props.get(key).toString()));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private Map getParameterTypeMap(Item item) {
+ Map result = new HashMap();
+
+ if(item instanceof WorkflowJob) {
+ List> properties = ((WorkflowJob)item).getAllProperties();
+
+ for(JobProperty property : properties) {
+ if (property instanceof ParametersDefinitionProperty) {
+ List paraDefs = ((ParametersDefinitionProperty)property).getParameterDefinitions();
+ for (ParameterDefinition paramDef : paraDefs) {
+ result.put(paramDef.getName(), paramDef.getType());
+ }
+ }
+ }
+ } else if(item instanceof AbstractItem) {
+ List actions = ((AbstractItem)item).getActions();
+
+ for(Action action : actions) {
+ if (action instanceof ParametersDefinitionProperty) {
+ List paraDefs = ((ParametersDefinitionProperty)action).getParameterDefinitions();
+ for (ParameterDefinition paramDef : paraDefs) {
+ result.put(paramDef.getName(), paramDef.getType());
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private String escapeItemName(String itemName) {
+ String result = itemName.replace("\'", "'");
+ return result;
+ }
+}
diff --git a/src/main/java/com/ibm/devops/connect/ConnectComputerListener.java b/src/main/java/com/ibm/devops/connect/ConnectComputerListener.java
new file mode 100644
index 0000000..899c0e5
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/ConnectComputerListener.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2017. All Rights Reserved.
+ *
+ * Note to U.S. Government Users Restricted Rights: Use,
+ * duplication or disclosure restricted by GSA ADP Schedule
+ * Contract with IBM Corp.
+ *******************************************************************************/
+package com.ibm.devops.connect;
+
+import hudson.slaves.ComputerListener;
+import hudson.model.Computer;
+import hudson.Extension;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.ibm.devops.connect.CloudItemListener;
+
+import com.ibm.devops.connect.Endpoints.EndpointManager;
+
+@Extension
+public class ConnectComputerListener extends ComputerListener {
+ public static final Logger log = LoggerFactory.getLogger(ConnectComputerListener.class);
+ private String logPrefix= "[IBM Cloud DevOps] ConnectComputerListener#";
+
+ private static CloudSocketComponent cloudSocketInstance;
+
+ @Override
+ public void onOnline(Computer c) {
+ String url = getConnectUrl();
+
+ logPrefix= logPrefix + "onOnline ";
+
+ CloudWorkListener listener = new CloudWorkListener();
+
+ if(cloudSocketInstance != null && cloudSocketInstance.connected()) {
+ cloudSocketInstance.disconnect();
+ }
+
+ cloudSocketInstance = new CloudSocketComponent(listener, url);
+
+ try {
+ log.info(logPrefix + "Connecting to Cloud Services...");
+ getCloudSocketInstance().connectToCloudServices();
+ } catch (Exception e) {
+ log.error(logPrefix + "Exception caught while connecting to Cloud Services: " + e);
+ }
+ }
+
+ private String getConnectUrl() {
+ EndpointManager em = new EndpointManager();
+ return em.getConnectEndpoint();
+ }
+
+ public CloudSocketComponent getCloudSocketInstance() {
+ return ConnectComputerListener.cloudSocketInstance;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/DevOpsGlobalConfiguration.java b/src/main/java/com/ibm/devops/connect/DevOpsGlobalConfiguration.java
new file mode 100644
index 0000000..58ced02
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/DevOpsGlobalConfiguration.java
@@ -0,0 +1,160 @@
+/*
+
+
+ Copyright 2016, 2017 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect;
+
+import java.util.List;
+
+import hudson.CopyOnWrite;
+import hudson.Extension;
+import hudson.model.Computer;
+import hudson.util.ListBoxModel;
+import jenkins.model.GlobalConfiguration;
+import net.sf.json.JSONObject;
+import org.kohsuke.stapler.StaplerRequest;
+import org.kohsuke.stapler.QueryParameter;
+import org.kohsuke.stapler.StaplerResponse;
+import org.kohsuke.stapler.AncestorInPath;
+import hudson.util.FormFieldValidator;
+import com.ibm.devops.connect.CloudSocketComponent;
+import com.ibm.devops.connect.ConnectComputerListener;
+
+import com.cloudbees.plugins.credentials.CredentialsMatchers;
+import com.cloudbees.plugins.credentials.CredentialsProvider;
+import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
+import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
+import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
+import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
+import hudson.security.ACL;
+import jenkins.model.Jenkins;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+/**
+ * Created by lix on 7/20/17.
+ */
+@Extension(ordinal = 100)
+public class DevOpsGlobalConfiguration extends GlobalConfiguration {
+
+ @CopyOnWrite
+ private volatile String syncId;
+ private volatile String syncToken;
+ private String credentialsId;
+
+ public DevOpsGlobalConfiguration() {
+ load();
+ }
+
+ public String getSyncId() {
+ return syncId;
+ }
+
+ public void setSyncId(String syncId) {
+ this.syncId = syncId;
+ save();
+ }
+
+ public String getSyncToken() {
+ return syncToken;
+ }
+
+ public void setSyncToken(String syncToken) {
+ this.syncToken = syncToken;
+ save();
+ }
+
+ public String getCredentialsId() {
+ return credentialsId;
+ }
+
+ public void setCredentialsId(String crendentialsId) {
+ this.credentialsId = credentialsId;
+ save();
+ }
+
+ @Override
+ public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
+ // To persist global configuration information,
+ // set that to properties and call save().
+ syncId = formData.getString("syncId");
+ syncToken = formData.getString("syncToken");
+ credentialsId = formData.getString("credentialsId");
+ save();
+
+ reconnectCloudSocket();
+
+ return super.configure(req,formData);
+ }
+
+ // for the future multi-region use
+ public ListBoxModel doFillRegionItems() {
+ ListBoxModel items = new ListBoxModel();
+ return items;
+ }
+
+ @Deprecated
+ public void doTestConnection(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
+ new FormFieldValidator(req, rsp, true) {
+ @Override
+ protected void check() throws IOException, ServletException {
+ CloudSocketComponent socket = new ConnectComputerListener().getCloudSocketInstance();
+ if(socket.connected()) {
+ ok("Success - Connected to IBM Cloud Service");
+ } else {
+ String cause = socket.getCauseOfFailure();
+ if(cause != null) {
+ error("Not connected to IBM Cloud Services - " + cause);
+ } else {
+ error("Not connected to IBM Cloud Services - Please ensure that the current values are applied");
+ }
+ }
+ }
+ }.process();
+ }
+
+ /**
+ * This method is called to populate the credentials list on the Jenkins config page.
+ */
+ public ListBoxModel doFillCredentialsIdItems(@QueryParameter("target") final String target) {
+ StandardListBoxModel result = new StandardListBoxModel();
+ result.includeEmptyValue();
+ result.withMatching(CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class),
+ CredentialsProvider.lookupCredentials(
+ StandardUsernameCredentials.class,
+ Jenkins.getInstance(),
+ ACL.SYSTEM,
+ URIRequirementBuilder.fromUri(target).build()
+ )
+ );
+ return result;
+ }
+
+ public StandardUsernamePasswordCredentials getCredentialsObj() {
+ List standardCredentials = CredentialsProvider.lookupCredentials(
+ StandardUsernamePasswordCredentials.class,
+ Jenkins.getInstance(),
+ ACL.SYSTEM);
+
+ StandardUsernamePasswordCredentials credentials =
+ CredentialsMatchers.firstOrNull(standardCredentials, CredentialsMatchers.withId(this.credentialsId));
+
+ return credentials;
+ }
+
+ private void reconnectCloudSocket() {
+ ConnectComputerListener connectComputerListener = new ConnectComputerListener();
+
+ connectComputerListener.onOnline(Computer.currentComputer());
+ }
+}
diff --git a/src/main/java/com/ibm/devops/connect/Endpoints/EndpointManager.java b/src/main/java/com/ibm/devops/connect/Endpoints/EndpointManager.java
new file mode 100644
index 0000000..d63d797
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Endpoints/EndpointManager.java
@@ -0,0 +1,30 @@
+package com.ibm.devops.connect.Endpoints;
+
+public class EndpointManager {
+
+ // TODO: Make configurable at build time or otherwise
+ //private static String profile = "YP";
+ private static String profile = "YS1";
+
+ private IEndpoints endpointProvider;
+
+ public EndpointManager() {
+ if(profile.equals("YS1")) {
+ endpointProvider = new EndpointsYS1();
+ } else {
+ endpointProvider = new EndpointsYP();
+ }
+ }
+
+ public String getSyncApiEndpoint() {
+ return endpointProvider.getSyncApiEndpoint();
+ }
+
+ public String getSyncStoreEndpoint() {
+ return endpointProvider.getSyncStoreEndpoint();
+ }
+
+ public String getConnectEndpoint() {
+ return endpointProvider.getConnectEndpoint();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/Endpoints/EndpointsYP.java b/src/main/java/com/ibm/devops/connect/Endpoints/EndpointsYP.java
new file mode 100644
index 0000000..41e457e
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Endpoints/EndpointsYP.java
@@ -0,0 +1,19 @@
+package com.ibm.devops.connect.Endpoints;
+
+public class EndpointsYP implements IEndpoints {
+ private static final String SYNC_API_ENPOINT = "https://ucreporting-sync-api.mybluemix.net/";
+ private static final String SYNC_STORE_ENPOINT = "https://uccloud-sync-store.mybluemix.net/";
+ private static final String CONNECT_ENPOINT = "https://uccloud-connect.mybluemix.net";
+
+ public String getSyncApiEndpoint() {
+ return SYNC_API_ENPOINT;
+ }
+
+ public String getSyncStoreEndpoint() {
+ return SYNC_STORE_ENPOINT;
+ }
+
+ public String getConnectEndpoint() {
+ return CONNECT_ENPOINT;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/Endpoints/EndpointsYS1.java b/src/main/java/com/ibm/devops/connect/Endpoints/EndpointsYS1.java
new file mode 100644
index 0000000..9a7ca2a
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Endpoints/EndpointsYS1.java
@@ -0,0 +1,19 @@
+package com.ibm.devops.connect.Endpoints;
+
+public class EndpointsYS1 implements IEndpoints {
+ private static final String SYNC_API_ENPOINT = "https://ucreporting-sync-api-stage1.stage1.mybluemix.net/";
+ private static final String SYNC_STORE_ENPOINT = "https://uccloud-sync-store-stage1.stage1.mybluemix.net/";
+ private static final String CONNECT_ENPOINT = "https://uccloud-connect-stage1.stage1.mybluemix.net";
+
+ public String getSyncApiEndpoint() {
+ return SYNC_API_ENPOINT;
+ }
+
+ public String getSyncStoreEndpoint() {
+ return SYNC_STORE_ENPOINT;
+ }
+
+ public String getConnectEndpoint() {
+ return CONNECT_ENPOINT;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/Endpoints/IEndpoints.java b/src/main/java/com/ibm/devops/connect/Endpoints/IEndpoints.java
new file mode 100644
index 0000000..4b50ebf
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Endpoints/IEndpoints.java
@@ -0,0 +1,11 @@
+package com.ibm.devops.connect.Endpoints;
+
+public interface IEndpoints {
+
+ public String getSyncApiEndpoint();
+
+ public String getSyncStoreEndpoint();
+
+ public String getConnectEndpoint();
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/IWorkListener.java b/src/main/java/com/ibm/devops/connect/IWorkListener.java
new file mode 100644
index 0000000..705d4ca
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/IWorkListener.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Licensed Materials - Property of IBM
+ * (c) Copyright IBM Corporation 2017. All Rights Reserved.
+ *
+ * Note to U.S. Government Users Restricted Rights: Use,
+ * duplication or disclosure restricted by GSA ADP Schedule
+ * Contract with IBM Corp.
+ *******************************************************************************/
+package com.ibm.devops.connect;
+
+import com.ibm.cloud.urbancode.connect.client.Listener;
+
+public interface IWorkListener extends Listener {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/JenkinsIntegrationId.java b/src/main/java/com/ibm/devops/connect/JenkinsIntegrationId.java
new file mode 100644
index 0000000..84b8d2e
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/JenkinsIntegrationId.java
@@ -0,0 +1,32 @@
+package com.ibm.devops.connect;
+
+import org.jenkinsci.plugins.uniqueid.IdStore;
+import com.ibm.devops.connect.DevOpsGlobalConfiguration;
+import jenkins.model.Jenkins;
+
+public class JenkinsIntegrationId {
+ public JenkinsIntegrationId () {
+
+ }
+
+ public String getIntegrationId() {
+ String result = getSyncId() + "_" + getJenkinsId();
+ return result;
+ }
+
+ private String getJenkinsId() {
+ String jenkinsId;
+ if (IdStore.getId(Jenkins.getInstance()) != null) {
+ jenkinsId = IdStore.getId(Jenkins.getInstance());
+ } else {
+ IdStore.makeId(Jenkins.getInstance());
+ jenkinsId = IdStore.getId(Jenkins.getInstance());
+ }
+
+ return jenkinsId;
+ }
+
+ private String getSyncId() {
+ return Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/JenkinsJob.java b/src/main/java/com/ibm/devops/connect/JenkinsJob.java
new file mode 100644
index 0000000..bd79cc2
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/JenkinsJob.java
@@ -0,0 +1,143 @@
+/*
+
+
+ Copyright 2017 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect;
+
+import hudson.model.*;
+import hudson.model.Item;
+import hudson.model.ParametersDefinitionProperty;
+import hudson.model.queue.SubTask;
+import hudson.model.ChoiceParameterDefinition;
+import hudson.model.PasswordParameterDefinition;
+import com.cloudbees.plugins.credentials.CredentialsParameterDefinition;
+import hudson.model.BooleanParameterDefinition;
+
+import java.util.Collection;
+
+import net.sf.json.JSONObject;
+import net.sf.json.JSONArray;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.jenkinsci.plugins.uniqueid.IdStore;
+
+import java.util.List;
+import jenkins.model.Jenkins;
+import org.jenkinsci.plugins.workflow.job.WorkflowJob;
+
+/**
+ * Jenkins server
+ */
+
+public class JenkinsJob {
+ final private Item item;
+ public static final Logger log = LoggerFactory.getLogger(JenkinsJob.class);
+
+ public JenkinsJob (Item item) {
+ this.item= item;
+ }
+ // TODO: see what this guy can do for us:
+ // - start: start a job
+ // - getStatus: get the status of a job
+ // - get build history
+ // - stop / cancel
+ // - other stuff?
+ public JSONObject toJson() {
+
+ String displayName= this.item.getDisplayName();
+ String name= this.item.getName();
+ String fullName= this.item.getFullName();
+ String jobUrl= this.item.getUrl();
+
+ JSONObject jobToJson = new JSONObject();
+ jobToJson.put("displayName", displayName);
+ jobToJson.put("name", name);
+ jobToJson.put("fullName", fullName);
+ jobToJson.put("jobUrl", jobUrl);
+ jobToJson.put("jenkinsClass", this.item.getClass());
+
+ String jobId;
+
+ if(IdStore.getId(this.item) != null) {
+ jobId = IdStore.getId(this.item);
+ } else {
+ IdStore.makeId(this.item);
+ jobId = IdStore.getId(this.item);
+ }
+
+ jobToJson.put("id", jobId);
+ jobToJson.put("instanceType", "JENKINS");
+ //jobToJson.put("instanceName", Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getInstanceName());
+
+ if(this.item instanceof WorkflowJob) {
+ jobToJson.put("isPipeline", true);
+ // TODO: Find a way to get Stage definitions
+ } else {
+ jobToJson.put("isPipeline", false);
+ }
+
+ jobToJson.put("params", getJobParams());
+
+ return jobToJson;
+ }
+
+ private JSONArray getJobParams() {
+ JSONArray result = new JSONArray();
+
+ if (this.item instanceof WorkflowJob) {
+ ParametersDefinitionProperty paramDefProperty = ((WorkflowJob)this.item).getProperty(ParametersDefinitionProperty.class);
+ if (paramDefProperty != null) {
+ List paramDefs = paramDefProperty.getParameterDefinitions();
+ for (ParameterDefinition paramDef : paramDefs) {
+ result.add(convertJobParameter(paramDef));
+ }
+ }
+ } else if (this.item instanceof AbstractProject) {
+ List actions = ((AbstractProject)this.item).getActions();
+
+ for(Action action : actions) {
+ if (action instanceof ParametersDefinitionProperty) {
+ List paraDefs = ((ParametersDefinitionProperty)action).getParameterDefinitions();
+ for (ParameterDefinition paramDef : paraDefs) {
+ result.add(convertJobParameter(paramDef));
+ }
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private JSONObject convertJobParameter(ParameterDefinition paramDef) {
+ JSONObject result = new JSONObject();
+ result.put("name", paramDef.getName());
+ result.put("type", paramDef.getType());
+ result.put("description", paramDef.getDescription());
+ ParameterValue pValue = paramDef.getDefaultParameterValue();
+ if (pValue != null) {
+ result.put("defaultValue", pValue.getValue());
+ }
+
+ if(paramDef instanceof ChoiceParameterDefinition) {
+ List options = ((ChoiceParameterDefinition)paramDef).getChoices();
+ result.put("options", options);
+ }
+
+ return result;
+ }
+}
diff --git a/src/main/java/com/ibm/devops/connect/JenkinsServer.java b/src/main/java/com/ibm/devops/connect/JenkinsServer.java
new file mode 100644
index 0000000..005328e
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/JenkinsServer.java
@@ -0,0 +1,220 @@
+/*
+
+
+ Copyright 2017 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect;
+
+import com.cloudbees.hudson.plugins.folder.Folder;
+
+import com.cloudbees.plugins.credentials.*;
+import com.cloudbees.plugins.credentials.common.*;
+import com.cloudbees.plugins.credentials.domains.*;
+import com.cloudbees.plugins.credentials.impl.*;
+
+import hudson.model.*;
+import hudson.model.Item;
+import hudson.model.TopLevelItem;
+
+import hudson.security.AuthorizationStrategy;
+import hudson.security.FullControlOnceLoggedInAuthorizationStrategy;
+import hudson.security.SecurityRealm;
+
+import java.io.ByteArrayInputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+
+import jenkins.model.Jenkins;
+
+import net.sf.json.*;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Jenkins server
+ */
+
+public class JenkinsServer {
+ public static final Logger log = LoggerFactory.getLogger(JenkinsServer.class);
+ private static String logPrefix= "[IBM Cloud DevOps] JenkinsServer#";
+
+ // creds
+ private static String BLX_CREDS= "IBM_CLOUD_DEVOPS_CREDS_API";
+ private static String BLX_CREDS_DESC= "IBM DevOps Bluemix credentials";
+ // folder and job
+ private static String FOLDER_SPEC= "Folder created by the IBM Devops plugin";
+ private static String jobSrc= "\r\n\r\n \r\n false\r\n \r\n \r\n \r\n \r\n * * * * *\r\n false\r\n \r\n \r\n \r\n \r\n \r\n \r\n 2\r\n \r\n \r\n https://github.com/ejodet/discovery-nodejs\r\n \r\n \r\n \r\n \r\n */mastertoto\r\n \r\n \r\n false\r\n \r\n \r\n \r\n Jenkinsfile\r\n true\r\n \r\n \r\n";
+
+ public static Collection getJobNames() {
+ log.debug(logPrefix + "getJobNames - get the list of job names");
+ Collection allJobNames= Jenkins.getInstance().getJobNames();
+ log.debug(logPrefix + "getJobNames - retrieved " + allJobNames.size() + " JobNames");
+ for (Iterator iterator = allJobNames.iterator(); iterator.hasNext();) {
+
+ String aJobName = (String) iterator.next();
+ log.debug(logPrefix + "job: " + aJobName);
+ }
+ return Jenkins.getInstance().getJobNames();
+ }
+
+ public static List getAllItems() {
+ log.debug(logPrefix + "getAllItems - get the list of all items");
+ List allItems= Jenkins.getInstance().getAllItems();
+ if (allItems.size() == 0) { // ensure we're able to list all items
+ AuthorizationStrategy authorizationStrategy= Jenkins.getInstance().getAuthorizationStrategy();
+ if (authorizationStrategy instanceof FullControlOnceLoggedInAuthorizationStrategy) {
+ // allow anoymous read in order to get all items
+ FullControlOnceLoggedInAuthorizationStrategy strat= (FullControlOnceLoggedInAuthorizationStrategy) authorizationStrategy;
+ // remember previous settings
+ boolean isAllowAnonymousRead= strat.isAllowAnonymousRead();
+ strat.setAllowAnonymousRead(true);
+ allItems= Jenkins.getInstance().getAllItems();
+ strat.setAllowAnonymousRead(isAllowAnonymousRead);
+ Jenkins.getInstance().setAuthorizationStrategy(strat);
+ }
+ }
+ log.debug(logPrefix + "getAllItems - Retrieved " + allItems.size() + " projects");
+ return allItems;
+ }
+
+ public static Item getItemByName(String itemName) {
+ log.info(logPrefix + "Retrieving project " + itemName);
+ List allProjects= JenkinsServer.getAllItems();
+
+ for (Item anItem : allProjects) {
+ String aName = anItem.getFullName();
+ log.info(logPrefix + "project " + aName);
+ if (itemName.equals(aName)) {
+ log.info(logPrefix + "Project " + itemName + " retrieved!");
+ return anItem;
+ }
+ }
+ log.info(logPrefix + "Project " + itemName + " not found!");
+ return null;
+ }
+
+ public static void createJob(JSONObject newJob) {
+ log.debug(logPrefix + "createJob - Creating a new job.");
+ if(validCreationRequest(newJob)) {
+ // get current security settings
+ SecurityRealm securityRealm= Jenkins.getInstance().getSecurityRealm();
+ AuthorizationStrategy authorizationStrategy= Jenkins.getInstance().getAuthorizationStrategy();
+
+ // temporarily disable security as we are not allowed to create jobs as anonymous
+ disableSecurity();
+ try {
+ // create creds if necessary
+ createCredentials(newJob) ;
+ JSONObject props = newJob.getJSONObject("props");
+ // create folder
+ String folderName= props.get("folderName").toString();
+ createFolder(folderName);
+ // verify folder was created
+ Folder targetFolder= getFolder(folderName);
+ if (targetFolder == null) {
+ log.debug(logPrefix + "createJob - target folder not retrieved. Exiting creation process");
+ } else {
+ log.debug(logPrefix + "createJob - target folder retrieved !!!!!");
+ // create job in target folder
+ String jobSrc= props.get("source").toString();
+ String jobName= props.get("jobName").toString();
+ Collection existingJobs= getJobNames();
+ if (existingJobs.contains(jobName)) {
+ // do not create
+ log.debug(logPrefix + "Job " + jobName + " already exists.");
+ } else {
+ createJobInFolder(targetFolder, jobName, jobSrc);
+ }
+ }
+ } catch (Exception e) {
+ log.error(logPrefix + "An unexpected error occurred while creating job.");
+ e.printStackTrace();
+ } finally {
+ // be sure to re-enable security
+ Jenkins.getInstance().setSecurityRealm(securityRealm);
+ Jenkins.getInstance().setAuthorizationStrategy(authorizationStrategy);
+ }
+ }
+ }
+
+ private static void createCredentials(JSONObject newJob) {
+ if(newJob.has("props")) {
+ JSONObject props = newJob.getJSONObject("props");
+ if (props.has("userName") && props.has("password")) { // not all jobs require creds creation
+ try {
+ log.debug(logPrefix + "createCredentials - creating " + BLX_CREDS + " credentials.");
+ Credentials creds = (Credentials) new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, BLX_CREDS, BLX_CREDS_DESC, props.get("userName").toString(), props.get("password").toString());
+ SystemCredentialsProvider.getInstance().getCredentials().add(creds);
+ SystemCredentialsProvider.getInstance().save();
+ log.debug(logPrefix + "createCredentials " + BLX_CREDS + " successfully created.");
+ } catch (Exception e) {
+ log.error(logPrefix + "createCredentials - unable to create " + BLX_CREDS + " credentials.");
+ e.printStackTrace();
+ }
+ } else {
+ log.debug(logPrefix + "createCredentials - credentials creation not required.");
+ }
+ }
+ }
+
+ private static boolean validCreationRequest(JSONObject newJob) {
+ log.debug(logPrefix + "validCreationRequest - Validating creation payload.");
+ boolean valid= false;
+ if(newJob.has("props")) {
+ JSONObject props = newJob.getJSONObject("props");
+ if (props.has("folderName") && props.has("jobName") && props.has("source")) {
+ log.debug(logPrefix + "validCreationRequest - Payload is valid.");
+ valid= true;
+ } else {
+ log.error(logPrefix + "validCreationRequest - Payload is not valid!");
+ }
+ }
+ return valid;
+ }
+
+ private static void createFolder(String folderName) {
+ log.debug(logPrefix + "createFolder - Creating folder " + folderName);
+ try {
+ Jenkins.getInstance().createProjectFromXML(folderName, new ByteArrayInputStream(FOLDER_SPEC.getBytes()));
+ log.debug(logPrefix + folderName + " was created successfully!");
+ } catch (Exception e) {
+ // folder might be existing
+ log.debug(logPrefix + folderName + " was not created.");
+ // e.printStackTrace();
+ }
+ }
+
+ private static void createJobInFolder(Folder targetFolder, String jobName, String source) {
+ log.debug(logPrefix + "createItem - Creating job " + jobName);
+ try {
+ targetFolder.createProjectFromXML(jobName, new ByteArrayInputStream(source.getBytes()));
+ log.debug(logPrefix + jobName + " was created successfully!");
+ } catch (Exception e) {
+ log.error(logPrefix + jobName + " was not created.");
+ e.printStackTrace();
+ }
+ }
+
+ private static void disableSecurity() {
+ log.debug(logPrefix + "disableSecurity()");
+ Jenkins.getInstance().disableSecurity();
+ }
+
+ private static Folder getFolder(String folderName) {
+ return (Folder) Jenkins.getInstance().getItem(folderName);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/OnConnectListener.java b/src/main/java/com/ibm/devops/connect/OnConnectListener.java
new file mode 100644
index 0000000..4fe0434
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/OnConnectListener.java
@@ -0,0 +1,16 @@
+package com.ibm.devops.connect;
+
+import com.ibm.cloud.urbancode.connect.client.ConnectSocket;
+import com.ibm.cloud.urbancode.connect.client.Listener;
+import com.ibm.devops.connect.CloudItemListener;
+import com.ibm.devops.connect.SecuredAction.BuildJobsList;
+
+public class OnConnectListener {
+ static final public Listener BUILD_JOBS_LIST = new Listener() {
+ @Override
+ public void call(ConnectSocket socket, String event, Object... args) {
+ BuildJobsList buildJobList = new BuildJobsList();
+ buildJobList.runAsJenkinsUser(null);
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/notification/Proxy.java b/src/main/java/com/ibm/devops/connect/Proxy.javaBOGUS
similarity index 100%
rename from src/main/java/com/ibm/devops/notification/Proxy.java
rename to src/main/java/com/ibm/devops/connect/Proxy.javaBOGUS
diff --git a/src/main/java/com/ibm/devops/connect/SecuredActions/AbstractSecuredAction.java b/src/main/java/com/ibm/devops/connect/SecuredActions/AbstractSecuredAction.java
new file mode 100644
index 0000000..dacf25f
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/SecuredActions/AbstractSecuredAction.java
@@ -0,0 +1,77 @@
+package com.ibm.devops.connect.SecuredAction;
+
+import org.acegisecurity.context.SecurityContextHolder;
+import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+import hudson.security.SecurityRealm;
+import org.acegisecurity.userdetails.UserDetails;
+import com.ibm.devops.connect.DevOpsGlobalConfiguration;
+import jenkins.model.Jenkins;
+import org.acegisecurity.Authentication;
+import org.acegisecurity.context.SecurityContextHolder;
+import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
+import org.acegisecurity.Authentication;
+import org.acegisecurity.AuthenticationException;
+import org.acegisecurity.BadCredentialsException;
+
+public abstract class AbstractSecuredAction {
+ protected abstract void run(ParamObj paramObj);
+
+ public class ParamObj {
+
+ }
+
+ public void runAsJenkinsUser(ParamObj paramObj) {
+
+ StandardUsernamePasswordCredentials providedCredentials = Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getCredentialsObj();
+
+ Authentication originalAuth = null;
+
+ if(providedCredentials != null) {
+ originalAuth = Jenkins.getInstance().getAuthentication();
+ Authentication authenticatedAuth = authenticateCredentials(providedCredentials);
+ SecurityContextHolder.getContext().setAuthentication(authenticatedAuth);
+ }
+
+ try{
+ run(paramObj);
+ } finally {
+ if (originalAuth != null) {
+ SecurityContextHolder.getContext().setAuthentication(originalAuth);
+ }
+ }
+
+ }
+
+ private Authentication authenticateCredentials(StandardUsernamePasswordCredentials providedCredentials) {
+ SecurityRealm realm = Jenkins.getInstance().getSecurityRealm();
+ SecurityRealm.SecurityComponents securityComponents = realm.createSecurityComponents();
+
+ Authentication auth = getAuth(providedCredentials, realm);
+
+ Authentication result = null;
+ if(auth != null) {
+ try {
+ result = securityComponents.manager.authenticate(auth);
+ } catch (AuthenticationException e) {
+ if ( e instanceof BadCredentialsException ) {
+ System.out.println("Wrong username or password");
+ } else {
+ System.out.println("Something else went wrong");
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private Authentication getAuth(StandardUsernamePasswordCredentials providedCredentials, SecurityRealm realm) {
+ UserDetails userDetails = realm.loadUserByUsername(providedCredentials.getUsername());
+
+ userDetails.getAuthorities();
+
+ Authentication auth = new UsernamePasswordAuthenticationToken (providedCredentials.getUsername(), providedCredentials.getPassword(), userDetails.getAuthorities());
+
+ return auth;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/SecuredActions/BuildJobsList.java b/src/main/java/com/ibm/devops/connect/SecuredActions/BuildJobsList.java
new file mode 100644
index 0000000..92a6fc8
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/SecuredActions/BuildJobsList.java
@@ -0,0 +1,19 @@
+package com.ibm.devops.connect.SecuredAction;
+
+import com.ibm.devops.connect.CloudItemListener;
+import jenkins.model.Jenkins;
+import hudson.model.AbstractItem;
+
+import java.util.List;
+
+public class BuildJobsList extends AbstractSecuredAction {
+
+ protected void run(AbstractSecuredAction.ParamObj paramObj) {
+ System.out.println("Running Operation As Another USER!!!!!!");
+
+ List allProjects= Jenkins.getInstance().getAllItems(AbstractItem.class);
+
+ CloudItemListener cil = new CloudItemListener();
+ cil.buildJobsList();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/SecuredActions/TriggerJob.java b/src/main/java/com/ibm/devops/connect/SecuredActions/TriggerJob.java
new file mode 100644
index 0000000..c286f9c
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/SecuredActions/TriggerJob.java
@@ -0,0 +1,35 @@
+package com.ibm.devops.connect.SecuredAction;
+
+import com.ibm.devops.connect.CloudWorkListener;
+import jenkins.model.Jenkins;
+import hudson.model.AbstractItem;
+
+
+import com.ibm.cloud.urbancode.connect.client.ConnectSocket;
+
+import java.util.List;
+
+public class TriggerJob extends AbstractSecuredAction {
+
+ protected void run(AbstractSecuredAction.ParamObj paramObj) {
+ System.out.println("Running Operation As Another USER!!!!!!");
+
+ TriggerJobParamObj triggerJobParamObj = (TriggerJobParamObj)paramObj;
+
+ CloudWorkListener cwl = new CloudWorkListener();
+ cwl.callSecured(triggerJobParamObj.socket, triggerJobParamObj.event, triggerJobParamObj.args);
+ }
+
+ public class TriggerJobParamObj extends AbstractSecuredAction.ParamObj {
+
+ public ConnectSocket socket;
+ public String event;
+ public Object[] args;
+
+ public TriggerJobParamObj(ConnectSocket socket, String event, Object... args) {
+ this.socket = socket;
+ this.event = event;
+ this.args = args;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/Status/AbstractJenkinsStatus.java b/src/main/java/com/ibm/devops/connect/Status/AbstractJenkinsStatus.java
new file mode 100644
index 0000000..a2f793a
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Status/AbstractJenkinsStatus.java
@@ -0,0 +1,266 @@
+package com.ibm.devops.connect.Status;
+
+import hudson.model.Run;
+import hudson.model.AbstractItem;
+import hudson.model.AbstractBuild;
+import hudson.model.TaskListener;
+import hudson.model.Action;
+import hudson.model.Describable;
+import hudson.EnvVars;
+import hudson.plugins.git.util.BuildData;
+import hudson.plugins.git.util.Build;
+import hudson.tasks.BuildStep;
+import hudson.FilePath;
+import hudson.model.Result;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jenkins.model.Jenkins;
+import org.jenkinsci.plugins.uniqueid.IdStore;
+import org.jenkinsci.plugins.workflow.job.WorkflowRun;
+import org.jenkinsci.plugins.workflow.graph.FlowNode;
+
+import com.ibm.devops.connect.DevOpsGlobalConfiguration;
+import com.ibm.devops.connect.CloudCause.JobStatus;
+import com.ibm.devops.connect.CloudCause;
+
+import com.ibm.devops.dra.EvaluateGate;
+import com.ibm.devops.dra.GatePublisherAction;
+
+import net.sf.json.JSONObject;
+
+import java.io.IOException;
+import java.lang.InterruptedException;
+import java.util.List;
+import java.util.Map;
+
+abstract class AbstractJenkinsStatus {
+ public static final Logger log = LoggerFactory.getLogger(AbstractJenkinsStatus.class);
+ // Run
+ protected Run run;
+
+ protected CloudCause cloudCause;
+
+ protected BuildStep buildStep;
+ protected FlowNode node;
+
+ protected Boolean newStep;
+ protected Boolean isFatal;
+
+ protected TaskListener taskListener;
+
+ protected EnvVars envVars;
+ protected CrAction crAction;
+
+ protected Boolean isPipeline;
+ protected Boolean isPaused;
+
+ protected void getOrCreateCrAction() {
+ // Get CrAction
+ List actions = run.getActions();
+ for(Action action : actions) {
+ if (action instanceof CrAction) {
+ crAction = (CrAction)action;
+ }
+ }
+
+ // If not, create crAction
+ if (crAction == null) {
+ crAction = new CrAction();
+ run.addAction(crAction);
+ }
+ }
+
+ protected void getEnvVars() {
+ try {
+ if(run != null && taskListener != null) {
+ this.envVars = run.getEnvironment(taskListener);
+ }
+ } catch (IOException ioEx) {
+ log.warn("IOException thrown while trying to retrieve EnvVars in constructor: " + ioEx);
+ } catch (InterruptedException intEx) {
+ log.warn("InterruptedException thrown while trying to retrieve EnvVars in constructor: " + intEx);
+ }
+ }
+
+ public JSONObject generateErrorStatus(String errorMessage) {
+ JSONObject result = new JSONObject();
+
+ cloudCause.addStep("Error: " + errorMessage, JobStatus.failure.toString(), "Failed due to error", true);
+
+ result.put("status", JobStatus.failure.toString());
+ result.put("timestamp", System.currentTimeMillis());
+ result.put("syncId", Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId());
+ result.put("steps", cloudCause.getStepsArray());
+ result.put("returnProps", cloudCause.getReturnProps());
+
+ if(run != null) {
+ result.put("url", Jenkins.getInstance().getRootUrl() + run.getUrl());
+ result.put("jobExternalId", getJobUniqueIdFromBuild());
+ result.put("name", run.getDisplayName());
+ } else {
+ result.put("url", Jenkins.getInstance().getRootUrl());
+ result.put("name", "Job Error");
+ }
+
+ return result;
+ }
+
+ private String getJobUniqueIdFromBuild() {
+ AbstractItem project = run.getParent();
+
+ String projectId;
+
+ if (IdStore.getId(project) != null) {
+ projectId = IdStore.getId(project);
+ } else {
+ IdStore.makeId(project);
+ projectId = IdStore.getId(project);
+ }
+
+ return projectId;
+ }
+
+ protected void evaluateSourceData() {
+ List actions = run.getActions();
+
+ // Try to get from the crAction
+ SourceData sd = crAction.getSourceData();
+ if(sd != null) {
+ cloudCause.setSourceData(sd);
+ }
+
+ if (envVars != null) {
+ for(Action action : actions) {
+ // If using Hudson Git Plugin
+ if (action instanceof BuildData) {
+ Map branchMap = ((BuildData)action).getBuildsByBranchName();
+
+ for(String branchName : branchMap.keySet()) {
+ Build gitBuild = branchMap.get(branchName);
+
+ if (gitBuild.getBuildNumber() == run.getNumber()) {
+ SourceData sourceData = new SourceData(branchName, gitBuild.getSHA1().getName(), "GIT");
+ sourceData.populateCommitMessage(taskListener, envVars, getWorkspaceFilePath(), gitBuild);
+
+ cloudCause.setSourceData(sourceData);
+ crAction.setSourceData(sourceData);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected void evaluateDRAData() {
+ DRAData data = cloudCause.getDRAData();
+
+ List actions = run.getActions();
+ if(data == null) {
+ data = crAction.getDRAData();
+ cloudCause.setDRAData(data);
+ }
+
+ if(data == null) {
+ data = new DRAData();
+ }
+
+ if (Jenkins.getInstance().getPlugin("ibm-cloud-devops") != null) {
+
+ //This block if for non-pipeline jobs to set additional data that we have access to
+ if (this.buildStep != null && this.buildStep instanceof EvaluateGate) {
+
+ EvaluateGate egs = (EvaluateGate)buildStep;
+
+ String environment = egs.getEnvName();
+ String applicationName = egs.getApplicationName();
+ String orgName = egs.getOrgName();
+ String toolchainName = egs.getToolchainName();
+
+ data.setApplicationName(applicationName);
+ data.setOrgName(orgName);
+ data.setToolchainName(toolchainName);
+ data.setEnvironment(environment);
+ }
+
+ for(Action action : actions) {
+ if (action instanceof GatePublisherAction) {
+ GatePublisherAction gpa = (GatePublisherAction)action;
+
+ String gateText = gpa.getText();
+ String riskDashboardLink = gpa.getRiskDashboardLink();
+ String decision = gpa.getDecision();
+ String policy = gpa.getPolicyName();
+
+ data.setGateText(gateText);
+ data.setDecision(decision);
+ data.setRiskDahboardLink(riskDashboardLink);
+ data.setPolicy(policy);
+ data.setBuildNumber(Integer.toString(run.getNumber()));
+
+ crAction.setDRAData(data);
+ cloudCause.setDRAData(data);
+ }
+ }
+ }
+ }
+
+ private void evaluateEnvironment() {
+ if( envVars != null ) {
+ crAction.updateEnvProperties(envVars);
+ }
+ }
+
+ public JSONObject generate() {
+ JSONObject result = new JSONObject();
+
+ evaluateSourceData();
+ evaluateDRAData();
+ evaluateEnvironment();
+
+ if(isPipeline) {
+ evaluatePipelineStep();
+ } else {
+ evaluateBuildStep();
+ }
+
+ if (run.getResult() == null) {
+ if(run.isBuilding()) {
+ result.put("status", JobStatus.started.toString());
+ } else {
+ result.put("status", JobStatus.unstarted.toString());
+ }
+ } else {
+ if(run.getResult() == Result.SUCCESS) {
+ result.put("status", JobStatus.success.toString());
+ } else {
+ result.put("status", JobStatus.failure.toString());
+ }
+ }
+
+ result.put("timestamp", System.currentTimeMillis());
+ result.put("syncId", Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getSyncId());
+ result.put("name", run.getDisplayName());
+ result.put("steps", cloudCause.getStepsArray());
+ result.put("url", Jenkins.getInstance().getRootUrl() + run.getUrl());
+ result.put("returnProps", cloudCause.getReturnProps());
+ result.put("isPipeline", isPipeline);
+ result.put("isPaused", isPaused);
+ result.put("jobName", run.getParent().getName());
+ result.put("jobExternalId", getJobUniqueIdFromBuild());
+ result.put("sourceData", cloudCause.getSourceDataJson());
+ result.put("draData", cloudCause.getDRADataJson());
+ result.put("crProperties", crAction.getCrProperties());
+ result.put("envProperties", crAction.getEnvProperties());
+
+ return result;
+ }
+
+ abstract protected FilePath getWorkspaceFilePath();
+
+ abstract protected void evaluatePipelineStep();
+
+ abstract protected void evaluateBuildStep();
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/Status/CrAction.java b/src/main/java/com/ibm/devops/connect/Status/CrAction.java
new file mode 100644
index 0000000..878ae72
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Status/CrAction.java
@@ -0,0 +1,63 @@
+package com.ibm.devops.connect.Status;
+
+import hudson.model.Action;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class CrAction implements Action {
+
+ private DRAData draData;
+ private SourceData sourceData;
+ private Map crProperties = new TreeMap();
+ private Map envProperties = new TreeMap();
+
+ public CrAction() {
+ }
+
+ public DRAData getDRAData() {
+ return draData;
+ }
+
+ public void setDRAData (DRAData draData) {
+ this.draData = draData;
+ }
+
+ public SourceData getSourceData() {
+ return sourceData;
+ }
+
+ public void setSourceData (SourceData sourceData) {
+ this.sourceData = sourceData;
+ }
+
+ public void updateCrProperties (Map properties) {
+ this.crProperties.putAll(properties);
+ }
+
+ public Map getCrProperties () {
+ return crProperties;
+ }
+
+ public void updateEnvProperties (Map properties) {
+ this.envProperties.putAll(properties);
+ }
+
+ public Map getEnvProperties () {
+ return envProperties;
+ }
+
+ @Override
+ public String getIconFileName() {
+ return null;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return null;
+ }
+
+ @Override
+ public String getUrlName() {
+ return null;
+ }
+}
diff --git a/src/main/java/com/ibm/devops/connect/Status/DRAData.java b/src/main/java/com/ibm/devops/connect/Status/DRAData.java
new file mode 100644
index 0000000..0b5ba2f
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Status/DRAData.java
@@ -0,0 +1,76 @@
+package com.ibm.devops.connect.Status;
+
+import net.sf.json.JSONObject;
+import java.util.Set;
+
+public class DRAData {
+
+ private String applicationName;
+ private String orgName;
+ private String toolchainName;
+ private String environment;
+ private String buildNumber;
+ private String policy;
+ private String gateText;
+ private String decision;
+ private String riskDahboardLink;
+
+
+ private String type;
+ private Set remoteUrls;
+
+ public DRAData() {
+ }
+
+ public void setApplicationName (String applicationName) {
+ this.applicationName = applicationName;
+ }
+
+ public void setOrgName (String orgName) {
+ this.orgName = orgName;
+ }
+
+ public void setToolchainName(String toolchainName) {
+ this.toolchainName = toolchainName;
+ }
+
+ public void setEnvironment (String environment) {
+ this.environment = environment;
+ }
+
+ public void setBuildNumber (String buildNumber) {
+ this.buildNumber = buildNumber;
+ }
+
+ public void setPolicy (String policy) {
+ this.policy = policy;
+ }
+
+ public void setGateText (String gateText) {
+ this.gateText = gateText;
+ }
+
+ public void setDecision (String decision) {
+ this.decision = decision;
+ }
+
+ public void setRiskDahboardLink (String riskDahboardLink) {
+ this.riskDahboardLink = riskDahboardLink;
+ }
+
+ public JSONObject toJson() {
+ JSONObject result = new JSONObject();
+
+ result.put("applicationName", applicationName);
+ result.put("orgName", applicationName);
+ result.put("toolchainName", toolchainName);
+ result.put("environment", environment);
+ result.put("buildNumber", buildNumber);
+ result.put("policy", policy);
+ result.put("gateText", gateText);
+ result.put("decision", decision);
+ result.put("riskDahboardLink", riskDahboardLink);
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/Status/JenkinsJobStatus.java b/src/main/java/com/ibm/devops/connect/Status/JenkinsJobStatus.java
new file mode 100644
index 0000000..a78230d
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Status/JenkinsJobStatus.java
@@ -0,0 +1,87 @@
+/*
+
+
+ Copyright 2018 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect.Status;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import hudson.model.TaskListener;
+import hudson.FilePath;
+import hudson.model.Describable;
+import hudson.tasks.BuildStep;
+import hudson.model.AbstractBuild;
+import hudson.model.BuildListener;
+
+import java.io.File;
+
+import com.ibm.devops.connect.CloudCause.JobStatus;
+import com.ibm.devops.connect.CloudCause;
+
+import org.jenkinsci.plugins.workflow.actions.WorkspaceAction;
+
+/**
+ * Jenkins server
+ */
+
+public class JenkinsJobStatus extends AbstractJenkinsStatus {
+
+ public static final Logger log = LoggerFactory.getLogger(JenkinsJobStatus.class);
+
+ public JenkinsJobStatus(AbstractBuild build, CloudCause cloudCause, BuildStep buildStep, BuildListener buildListener, Boolean newStep, Boolean isFatal) {
+ this.run = build;
+ this.cloudCause = cloudCause;
+ this.buildStep = buildStep;
+ this.newStep = newStep;
+ this.isFatal = isFatal;
+ this.taskListener = buildListener;
+ this.isPaused = false;
+ this.isPipeline = false;
+
+ getEnvVars();
+ getOrCreateCrAction();
+ }
+
+ protected FilePath getWorkspaceFilePath() {
+ return ((AbstractBuild)run).getWorkspace();
+ }
+
+
+ protected void evaluateBuildStep() {
+ if(!(buildStep instanceof hudson.model.ParametersDefinitionProperty)) {
+ if (newStep) {
+ cloudCause.addStep(((Describable)buildStep).getDescriptor().getDisplayName(), JobStatus.started.toString(), "Started a build step", false);
+ } else {
+ String newStatus;
+ String message;
+ if (!isFatal) {
+ newStatus = JobStatus.success.toString();
+ message = "The build step finished and the job will continue.";
+ } else {
+ newStatus = JobStatus.failure.toString();
+ message = "The build step failed and the job can not continue.";
+ }
+
+ if (cloudCause.isCreatedByCR()) {
+ cloudCause.updateLastStep(((Describable)buildStep).getDescriptor().getDisplayName(), newStatus, message, isFatal);
+ }
+ }
+ }
+ }
+
+ protected void evaluatePipelineStep() {
+ // No Op
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/Status/JenkinsPipelineStatus.java b/src/main/java/com/ibm/devops/connect/Status/JenkinsPipelineStatus.java
new file mode 100644
index 0000000..5b8aac4
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Status/JenkinsPipelineStatus.java
@@ -0,0 +1,108 @@
+/*
+
+
+ Copyright 2018 IBM Corporation
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ */
+
+package com.ibm.devops.connect.Status;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import hudson.model.TaskListener;
+import hudson.FilePath;
+
+import java.io.File;
+
+import com.ibm.devops.connect.CloudCause.JobStatus;
+import com.ibm.devops.connect.CloudCause;
+
+import org.jenkinsci.plugins.workflow.flow.FlowExecution;
+import org.jenkinsci.plugins.workflow.job.WorkflowRun;
+import org.jenkinsci.plugins.workflow.graph.FlowNode;
+import org.jenkinsci.plugins.workflow.graph.FlowGraphWalker;
+
+import org.jenkinsci.plugins.workflow.actions.WorkspaceAction;
+
+/**
+ * Jenkins server
+ */
+
+public class JenkinsPipelineStatus extends AbstractJenkinsStatus {
+
+ private boolean shouldCheckSCM = false;
+
+ public static final Logger log = LoggerFactory.getLogger(JenkinsPipelineStatus.class);
+
+ public JenkinsPipelineStatus(WorkflowRun workflowRun, CloudCause cloudCause, FlowNode node, TaskListener listener, boolean newStep, boolean isPaused) {
+ this.run = workflowRun;
+ this.cloudCause = cloudCause;
+ this.node = node;
+ this.newStep = newStep;
+ this.isPaused = isPaused;
+ this.isPipeline = true;
+ this.taskListener = listener;
+
+ getEnvVars();
+ getOrCreateCrAction();
+
+ if (envVars != null) {
+ shouldCheckSCM = true;
+ }
+ }
+
+ protected FilePath getWorkspaceFilePath() {
+ FlowExecution exec = ((WorkflowRun)run).getExecution();
+ if(exec == null)
+ return null;
+
+ FlowGraphWalker w = new FlowGraphWalker(exec);
+ for (FlowNode n : w) {
+ if (n.getClass().getName().equals("org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode")) {
+ WorkspaceAction action = n.getAction(WorkspaceAction.class);
+ if(action != null) {
+ String node = action.getNode().toString();
+ String workspace = action.getPath().toString();
+ FilePath result = new FilePath(new File(workspace));
+
+ return result;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ protected void evaluatePipelineStep() {
+ if(newStep && node == null) {
+ cloudCause.addStep("Starting Jenkins Pipeline", JobStatus.success.toString(), "Successfully started pipeline...", false);
+ } else if(newStep && node != null) {
+ cloudCause.addStep(node.getDisplayName(), JobStatus.started.toString(), "Started stage", false);
+ } else if (isPaused && node != null) {
+ cloudCause.addStep(node.getDisplayName(), JobStatus.started.toString(), "Please acknowledge the Jenkins Pipeline input", false);
+ } else if(!newStep && node != null) {
+
+ if(node.getError() == null) {
+ if(cloudCause.isCreatedByCR()) {
+ cloudCause.updateLastStep(null, JobStatus.success.toString(), "Stage is successful", false);
+ } else {
+ cloudCause.addStep(null, JobStatus.success.toString(), "Stage is successful", false);
+ }
+ } else {
+ cloudCause.updateLastStep(null, JobStatus.failure.toString(), node.getError().getDisplayName(), false);
+ }
+ }
+ }
+
+ protected void evaluateBuildStep() {
+ // No Op
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/connect/Status/SourceData.java b/src/main/java/com/ibm/devops/connect/Status/SourceData.java
new file mode 100644
index 0000000..937079a
--- /dev/null
+++ b/src/main/java/com/ibm/devops/connect/Status/SourceData.java
@@ -0,0 +1,95 @@
+package com.ibm.devops.connect.Status;
+
+import net.sf.json.JSONObject;
+import java.util.Set;
+import hudson.EnvVars;
+import hudson.model.TaskListener;
+import hudson.FilePath;
+import hudson.plugins.git.util.Build;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.jenkinsci.plugins.gitclient.Git;
+import org.jenkinsci.plugins.gitclient.GitClient;
+import hudson.plugins.git.Revision;
+import org.eclipse.jgit.revwalk.RevCommit;
+import hudson.plugins.git.util.RevCommitRepositoryCallback;
+
+import java.io.IOException;
+import java.lang.InterruptedException;
+
+public class SourceData {
+ public static final Logger log = LoggerFactory.getLogger(SourceData.class);
+
+ private String branch;
+ private String revision;
+ private String scmName;
+ private String type;
+ private String shortMessage;
+ private String fullMessage;
+ private Set remoteUrls;
+
+ public SourceData(String branch, String revision, String type) {
+ this.branch = branch;
+ this.revision = revision;
+ this.type = type;
+ }
+
+ public void setBranch (String branch) {
+ this.branch = branch;
+ }
+
+ public void setRevision (String revision) {
+ this.revision = revision;
+ }
+
+ public void setScmName(String scmName) {
+ this.scmName = scmName;
+ }
+
+ public void setType (String type) {
+ this.type = type;
+ }
+
+ public void setRemoteUrls (Set remoteUrls) {
+ this.remoteUrls = remoteUrls;
+ }
+
+ public JSONObject toJson() {
+ JSONObject result = new JSONObject();
+
+ result.put("branch", branch);
+ result.put("revision", revision);
+ result.put("scmName", scmName);
+ result.put("type", type);
+ result.put("fullMessage", fullMessage);
+ result.put("shortMessage", shortMessage);
+ result.put("type", type);
+ if(remoteUrls != null) {
+ result.put("remoteUrls", remoteUrls.toArray());
+ }
+
+ return result;
+ }
+
+ public void populateCommitMessage(TaskListener listener, EnvVars envVars, FilePath workspace, Build gitBuild) {
+ try {
+ Git git = Git.with(listener, envVars);
+ if (workspace != null) {
+ git = git.in(workspace);
+ }
+
+ GitClient gitClient = git.getClient();
+ RevCommit commit = gitClient.withRepository(new RevCommitRepositoryCallback(gitBuild));
+
+ this.shortMessage = commit.getShortMessage();
+ this.fullMessage = commit.getFullMessage();
+
+ } catch (IOException ioEx) {
+ log.warn("IOException thrown while trying to retrieve commit message in populateCommitMessage: " + ioEx);
+ } catch (InterruptedException intEx) {
+ log.warn("InterruptException thrown while trying to retrieve commit message in populateCommitMessage: " + intEx);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/dra/AbstractDevOpsAction.java b/src/main/java/com/ibm/devops/dra/AbstractDevOpsAction.java
deleted file mode 100644
index febcf33..0000000
--- a/src/main/java/com/ibm/devops/dra/AbstractDevOpsAction.java
+++ /dev/null
@@ -1,976 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import com.cloudbees.plugins.credentials.CredentialsMatchers;
-import com.cloudbees.plugins.credentials.CredentialsProvider;
-import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
-import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
-import com.google.common.collect.ImmutableMap;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.ibm.devops.dra.steps.AbstractDevOpsStep;
-import hudson.EnvVars;
-import hudson.ProxyConfiguration;
-import hudson.model.*;
-import hudson.security.ACL;
-import hudson.tasks.Recorder;
-import hudson.util.ListBoxModel;
-import hudson.util.Secret;
-import jenkins.model.Jenkins;
-import org.apache.http.HttpHost;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.cloudfoundry.client.lib.CloudCredentials;
-import org.cloudfoundry.client.lib.CloudFoundryClient;
-import org.cloudfoundry.client.lib.CloudFoundryException;
-import org.cloudfoundry.client.lib.HttpProxyConfiguration;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.regex.Pattern;
-
-/**
- * Abstract DRA Builder to share common method between two different post-build actions
- */
-public abstract class AbstractDevOpsAction extends Recorder {
-
- public final static Logger LOGGER = Logger.getLogger(AbstractDevOpsAction.class.getName());
- public final static String ORG_NAME = "IBM_CLOUD_DEVOPS_ORG";
- public final static String APP_NAME = "IBM_CLOUD_DEVOPS_APP_NAME";
- public final static String TOOLCHAIN_ID = "IBM_CLOUD_DEVOPS_TOOLCHAIN_ID";
- public final static String USERNAME = "IBM_CLOUD_DEVOPS_CREDS_USR";
- public final static String PASSWORD = "IBM_CLOUD_DEVOPS_CREDS_PSW";
- public final static String RESULT_SUCCESS = "SUCCESS";
- public final static String RESULT_FAIL = "FAIL";
-
- private final static String ORG= "&&organization_guid:";
- private final static String SPACE= "&&space_guid:";
-
- private static Map TARGET_API_MAP = ImmutableMap.of(
- "production", "https://api.ng.bluemix.net",
- "dev", "https://api.stage1.ng.bluemix.net",
- "new", "https://api.stage1.ng.bluemix.net",
- "stage1", "https://api.stage1.ng.bluemix.net"
- );
-
- private static Map ORGANIZATIONS_URL_MAP = ImmutableMap.of(
- "production", "https://api.ng.bluemix.net/v2/organizations?q=name:",
- "dev", "https://api.stage1.ng.bluemix.net/v2/organizations?q=name:",
- "new", "https://api.stage1.ng.bluemix.net/v2/organizations?q=name:",
- "stage1", "https://api.stage1.ng.bluemix.net/v2/organizations?q=name:"
- );
-
- private static Map SPACES_URL_MAP = ImmutableMap.of(
- "production", "https://api.ng.bluemix.net/v2/spaces?q=name:",
- "dev", "https://api.stage1.ng.bluemix.net/v2/spaces?q=name:",
- "new", "https://api.stage1.ng.bluemix.net/v2/spaces?q=name:",
- "stage1", "https://api.stage1.ng.bluemix.net/v2/spaces?q=name:"
- );
-
- private static Map APPS_URL_MAP = ImmutableMap.of(
- "production", "https://api.ng.bluemix.net/v2/apps?q=name:",
- "dev", "https://api.stage1.ng.bluemix.net/v2/apps?q=name:",
- "new", "https://api.stage1.ng.bluemix.net/v2/apps?q=name:",
- "stage1", "https://api.stage1.ng.bluemix.net/v2/apps?q=name:"
- );
-
- private static Map TOOLCHAINS_URL_MAP = ImmutableMap.of(
- "production", "https://otc-api.ng.bluemix.net/api/v1/toolchains?organization_guid=",
- "dev", "https://otc-api.stage1.ng.bluemix.net/api/v1/toolchains?organization_guid=",
- "stage1", "https://otc-api-integration.stage1.ng.bluemix.net/api/v1/toolchains?organization_guid=",
- "new", "https://otc-api.stage1.ng.bluemix.net/api/v1/toolchains?organization_guid="
- );
-
- private static Map POLICIES_URL_MAP = ImmutableMap.of(
- "production", "https://dra.ng.bluemix.net/api/v4/organizations/{org_name}/toolchainids/{toolchain_name}/policies",
- "dev", "https://dev-dra.stage1.ng.bluemix.net/api/v4/organizations/{org_name}/toolchainids/{toolchain_name}/policies",
- "new", "https://new-dra.stage1.ng.bluemix.net/api/v4/organizations/{org_name}/toolchainids/{toolchain_name}/policies",
- "stage1", "https://dra.stage1.ng.bluemix.net/api/v4/organizations/{org_name}/toolchainids/{toolchain_name}/policies"
- );
-
- private static Map DLMS_ENV_MAP = ImmutableMap.of(
- "production", "https://dlms.ng.bluemix.net/v2",
- "dev", "https://dev-dlms.stage1.ng.bluemix.net/v2",
- "new", "https://new-dlms.stage1.ng.bluemix.net/v2",
- "stage1", "https://dlms.stage1.ng.bluemix.net/v2"
- );
-
- private static Map GATE_DECISION_ENV_MAP = ImmutableMap.of(
- "production", "https://dra.ng.bluemix.net/api/v4",
- "dev", "https://dev-dra.stage1.ng.bluemix.net/api/v4",
- "new", "https://new-dra.stage1.ng.bluemix.net/api/v4",
- "stage1", "https://dra.stage1.ng.bluemix.net/api/v4"
- );
-
- // Todo: need to get rid of ng and add env_id
- private static Map CONTROL_CENTER_ENV_MAP = ImmutableMap.of(
- "production", "https://console.ng.bluemix.net/devops/insights/#!/",
- "dev", "https://dev-console.stage1.ng.bluemix.net/devops/insights/#!/",
- "new", "https://new-console.stage1.ng.bluemix.net/devops/insights/#!/",
- "stage1", "https://console.stage1.ng.bluemix.net/devops/insights/#!/"
- );
-
- public static void printPluginVersion(ClassLoader loader, PrintStream printStream) {
- final Properties properties = new Properties();
- try {
- properties.load(loader.getResourceAsStream("plugin.properties"));
- printStream.println("[IBM Cloud DevOps] version: " + properties.getProperty("version"));
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- }
-
- /**
- * get the environment based on the console
- * @param consoleUrl
- */
- public static String getEnv(String consoleUrl) {
-
- if (Util.isNullOrEmpty(consoleUrl)) {
- return "production";
- } else if (consoleUrl.contains("dev-console.stage1.bluemix.net") || consoleUrl.contains("dev-console.stage1.ng.bluemix.net")) {
- return "dev";
- } else if (consoleUrl.contains("new-console.stage1.bluemix.net") || consoleUrl.contains("new-console.stage1.ng.bluemix.net")) {
- return "new";
- } else if (consoleUrl.contains("console.stage1.bluemix.net") || consoleUrl.contains("console.stage1.ng.bluemix.net")) {
- return "stage1";
- } else if (consoleUrl.contains("console.bluemix.net") || consoleUrl.contains("console.ng.bluemix.net")){
- return "production";
- } else {
- int start = consoleUrl.indexOf("console") + 8;
- int end = consoleUrl.indexOf("bluemix.net") - 1;
- String local = consoleUrl.substring(start, end);
- return local;
- }
- }
-
- /**
- * set the required env variables' HashMap for all steps
- * @param step
- * @param envVars
- * @return
- */
- public static HashMap setRequiredEnvVars(AbstractDevOpsStep step, EnvVars envVars) {
- HashMap requiredEnvVars = new HashMap<>();
- requiredEnvVars.put(ORG_NAME, Util.isNullOrEmpty(step.getOrgName()) ? envVars.get("IBM_CLOUD_DEVOPS_ORG") : step.getOrgName());
- requiredEnvVars.put(APP_NAME, Util.isNullOrEmpty(step.getApplicationName()) ? envVars.get("IBM_CLOUD_DEVOPS_APP_NAME") : step.getApplicationName());
- requiredEnvVars.put(TOOLCHAIN_ID, Util.isNullOrEmpty(step.getToolchainId()) ? envVars.get("IBM_CLOUD_DEVOPS_TOOLCHAIN_ID") : step.getToolchainId());
- requiredEnvVars.put(USERNAME, envVars.get("IBM_CLOUD_DEVOPS_CREDS_USR"));
- requiredEnvVars.put(PASSWORD, envVars.get("IBM_CLOUD_DEVOPS_CREDS_PSW"));
- return requiredEnvVars;
- }
-
- public static String chooseTargetAPI(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (TARGET_API_MAP.keySet().contains(environment)) {
- return TARGET_API_MAP.get(environment);
- } else {
- String api = TARGET_API_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
-
- return TARGET_API_MAP.get("production");
- }
-
- public static String chooseToolchainsUrl(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (TOOLCHAINS_URL_MAP.keySet().contains(environment)) {
- return TOOLCHAINS_URL_MAP.get(environment);
- } else {
- String api = TOOLCHAINS_URL_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
-
- return TOOLCHAINS_URL_MAP.get("production");
- }
-
- public static String chooseOrganizationsUrl(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (ORGANIZATIONS_URL_MAP.keySet().contains(environment)) {
- return ORGANIZATIONS_URL_MAP.get(environment);
- } else {
- String api = ORGANIZATIONS_URL_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
- return ORGANIZATIONS_URL_MAP.get("production");
- }
-
- public static String chooseSpacesUrl(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (SPACES_URL_MAP.keySet().contains(environment)) {
- return SPACES_URL_MAP.get(environment);
- } else {
- String api = SPACES_URL_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
-
- return SPACES_URL_MAP.get("production");
- }
-
- public static String chooseAppsUrl(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (APPS_URL_MAP.keySet().contains(environment)) {
- return APPS_URL_MAP.get(environment);
- } else {
- String api = APPS_URL_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
-
- return APPS_URL_MAP.get("production");
- }
-
- public static String choosePoliciesUrl(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (POLICIES_URL_MAP.keySet().contains(environment)) {
- return POLICIES_URL_MAP.get(environment);
- } else {
- String api = POLICIES_URL_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
-
- return POLICIES_URL_MAP.get("production");
- }
-
-
- /**
- * choose DLMS Url for different environment (production, stage1, new, dev)
- * @param environment
- * @return
- */
-
- public static String chooseDLMSUrl(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (DLMS_ENV_MAP.keySet().contains(environment)) {
- return DLMS_ENV_MAP.get(environment);
- } else {
- String api = DLMS_ENV_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
-
- return DLMS_ENV_MAP.get("production");
- }
-
- /**
- * choose DRA Url for different environment (production, stage1, new, dev)
- * @param environment
- * @return
- */
- public static String chooseDRAUrl(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (GATE_DECISION_ENV_MAP.keySet().contains(environment)) {
- return GATE_DECISION_ENV_MAP.get(environment);
- } else {
- String api = GATE_DECISION_ENV_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
-
- return GATE_DECISION_ENV_MAP.get("production");
- }
-
- /**
- * choose control center Url for different environment (production, stage1, new, dev)
- * @param environment
- * @return
- */
- public static String chooseControlCenterUrl(String environment) {
- if (!Util.isNullOrEmpty(environment)) {
- if (CONTROL_CENTER_ENV_MAP.keySet().contains(environment)) {
- return CONTROL_CENTER_ENV_MAP.get(environment);
- } else {
- String api = CONTROL_CENTER_ENV_MAP.get("production").replace("ng", environment);
- return api;
- }
- }
- return CONTROL_CENTER_ENV_MAP.get("production");
- }
-
- /**
- * check if the root url in the jenkins is set correctly
- * @param printStream
- * @return
- */
- public static boolean checkRootUrl(PrintStream printStream) {
-
- if (Util.isNullOrEmpty(Jenkins.getInstance().getRootUrl())) {
- printStream.println(
- "[IBM Cloud DevOps] The Jenkins global root url is not set. Please set it to use this postbuild Action. \"Manage Jenkins > Configure System > Jenkins URL\"");
- printStream.println("[IBM Cloud DevOps] Warning: You would not get the correct project url");
- return false;
- }
- return true;
- }
-
- /**
- * Get the Bluemix Token using Cloud Foundry as the authentication with DLMS and DRA backend
- * @param context - the current job
- * @param credentialsId - the credential id in Jenkins
- * @param targetAPI - the target api that used for logging in to the Bluemix
- * @return the bearer token
- */
- public static String getBluemixToken(Job context, String credentialsId, String targetAPI) throws Exception {
-
- try {
- List standardCredentials = CredentialsProvider.lookupCredentials(
- StandardUsernamePasswordCredentials.class,
- context,
- ACL.SYSTEM,
- URIRequirementBuilder.fromUri(targetAPI).build());
-
- StandardUsernamePasswordCredentials credentials =
- CredentialsMatchers.firstOrNull(standardCredentials, CredentialsMatchers.withId(credentialsId));
-
- if (credentials == null || credentials.getUsername() == null || credentials.getPassword() == null) {
- throw new Exception("Failed to get Credentials");
- }
- CloudCredentials cloudCredentials = new CloudCredentials(credentials.getUsername(), Secret.toString(credentials.getPassword()));
- if (cloudCredentials == null) {
- throw new Exception("Failed to get Cloud Credentials");
- }
-
- URL url = new URL(targetAPI);
- HttpProxyConfiguration configuration = buildProxyConfiguration(url);
-
- CloudFoundryClient client = new CloudFoundryClient(cloudCredentials, url, configuration, true);
- return "bearer " + client.login().toString();
-
- } catch (MalformedURLException e) {
- throw e;
- } catch (CloudFoundryException e) {
- throw e;
- }
- }
-
- public static String getBluemixToken(ItemGroup context, String credentialsId, String targetAPI) throws Exception {
-
- try {
- List standardCredentials = CredentialsProvider.lookupCredentials(
- StandardUsernamePasswordCredentials.class,
- context,
- ACL.SYSTEM,
- URIRequirementBuilder.fromUri(targetAPI).build());
-
- StandardUsernamePasswordCredentials credentials =
- CredentialsMatchers.firstOrNull(standardCredentials, CredentialsMatchers.withId(credentialsId));
-
- if (credentials == null || credentials.getUsername() == null || credentials.getPassword() == null) {
- throw new Exception("Failed to get Credentials");
- }
- CloudCredentials cloudCredentials = new CloudCredentials(credentials.getUsername(), Secret.toString(credentials.getPassword()));
- if (cloudCredentials == null) {
- throw new Exception("Failed to get Cloud Credentials");
- }
-
- URL url = new URL(targetAPI);
- HttpProxyConfiguration configuration = buildProxyConfiguration(url);
-
- CloudFoundryClient client = new CloudFoundryClient(cloudCredentials, url, configuration, true);
- return "bearer " + client.login().toString();
-
- } catch (MalformedURLException e) {
- throw e;
- } catch (CloudFoundryException e) {
- throw e;
- }
- }
-
- public static String getBluemixToken(String username, String password, String targetAPI) throws MalformedURLException, CloudFoundryException {
- try {
-
- CloudCredentials cloudCredentials = new CloudCredentials(username, password);
-
- URL url = new URL(targetAPI);
- HttpProxyConfiguration configuration = buildProxyConfiguration(url);
-
- CloudFoundryClient client = new CloudFoundryClient(cloudCredentials, url, configuration, true);
- return "bearer " + client.login().toString();
-
- } catch (MalformedURLException e) {
- throw e;
- } catch (CloudFoundryException e) {
- throw e;
- }
- }
-
- /**
- * build proxy for cloud foundry http connection
- * @param targetURL - target API URL
- * @return the full target URL
- */
- private static HttpProxyConfiguration buildProxyConfiguration(URL targetURL) {
- ProxyConfiguration proxyConfig = Jenkins.getInstance().proxy;
- if (proxyConfig == null) {
- return null;
- }
-
- String host = targetURL.getHost();
- for (Pattern p : proxyConfig.getNoProxyHostPatterns()) {
- if (p.matcher(host).matches()) {
- return null;
- }
- }
-
- return new HttpProxyConfiguration(proxyConfig.name, proxyConfig.port);
- }
-
- /**
- * get the root project
- * @param job - the source job
- * @return the root project
- */
- private static Job, ?> getRootProject(Job, ?> job) {
- if (job instanceof AbstractProject) {
- return ((AbstractProject,?>)job).getRootProject();
- } else {
- return job;
- }
- }
-
- // retrieve the "folder" (jenkins root if no folder used) for this build
- private static ItemGroup getItemGroup(Run, ?> build) {
- return getRootProject(build.getParent()).getParent();
- }
-
-
- /**
- * Recursive function to locate the triggered build
- * @param job - the target job
- * @param parent - the current job
- * @return the specific build of the target job
- */
- private static Run,?> getBuild(Job,?> job, Run,?> parent) {
- Run,?> result = null;
-
- // Upstream job for matrix will be parent project, not only individual configuration:
- List jobNames = new ArrayList<>();
- jobNames.add(job.getFullName());
- if ((job instanceof AbstractProject,?>) && ((AbstractProject,?>)job).getRootProject() != job) {
- jobNames.add(((AbstractProject,?>)job).getRootProject().getFullName());
- }
-
- List> upstreamBuilds = new ArrayList<>();
-
- for (Cause cause: parent.getCauses()) {
- if (cause instanceof Cause.UpstreamCause) {
- Cause.UpstreamCause upstream = (Cause.UpstreamCause) cause;
- Run, ?> upstreamRun = upstream.getUpstreamRun();
- if (upstreamRun != null) {
- upstreamBuilds.add(upstreamRun);
- }
- }
- }
-
- if (parent instanceof AbstractBuild) {
- AbstractBuild, ?> parentBuild = (AbstractBuild,?>)parent;
-
- Map parentUpstreamBuilds = parentBuild.getUpstreamBuilds();
- for (Map.Entry buildEntry : parentUpstreamBuilds.entrySet()) {
- upstreamBuilds.add(buildEntry.getKey().getBuildByNumber(buildEntry.getValue()));
- }
- }
-
- for (Run, ?> upstreamBuild : upstreamBuilds) {
- Run,?> run;
-
- if(upstreamBuild == null) {
- continue;
- }
- if (jobNames.contains(upstreamBuild.getParent().getFullName())) {
- // Use the 'job' parameter instead of directly the 'upstreamBuild', because of Matrix jobs.
- run = job.getBuildByNumber(upstreamBuild.getNumber());
- } else {
- // Figure out the parent job and do a recursive call to getBuild
- run = getBuild(job, upstreamBuild);
- }
-
- if (run != null){
- if ((result == null) || (result.getNumber() > run.getNumber())) {
- result = run;
- }
- }
-
- }
-
- return result;
- }
-
- /**
- * locate triggered build
- * @param build - the current running build of this job
- * @param name - the build job name that you are going to locate
- * @param printStream - logger
- * @return
- */
- public static Run,?> getTriggeredBuild(Run build, String name, EnvVars envVars, PrintStream printStream) {
- // if user specify the build job as current job or leave it empty
- if (name == null || name.isEmpty() || name.equals(build.getParent().getName())) {
- printStream.println("[IBM Cloud DevOps] Current job is the build job");
- return build;
- } else {
- name = envVars.expand(name);
- Job, ?> job = Jenkins.getInstance().getItem(name, getItemGroup(build), Job.class);
- if (job != null) {
- Run src = getBuild(job, build);
- if (src == null) {
- // if user runs the test job independently
- printStream.println("[IBM Cloud DevOps] Are you running the test job independently? Use the last successful build of the build job");
- src = job.getLastSuccessfulBuild();
- }
-
- return src;
- } else {
- // if user does not specify the build job or can not find the build job that user specifies
- printStream.println("[IBM Cloud DevOps] ERROR: Failed to find the build job, please check the build job name");
- return null;
- }
- }
- }
-
- /**
- * Get the build number
- * @param build
- * @return
- */
- public String getBuildNumber(String jobName, Run build) {
-
- String jName = "";
- Scanner s = new Scanner(jobName).useDelimiter("/");
- while(s.hasNext()){ // this will loop through the string until the last string(job name) is reached.
- jName = s.next();
- }
- s.close();
-
- String buildNumber = jName + ":" + build.getNumber();
- return buildNumber;
- }
-
- /**
- * Get a list of toolchains using given token and organization name.
- * @param token
- * @param orgName
- * @return
- */
- public static ListBoxModel getToolchainList(String token, String orgName, String environment, Boolean debug_mode) {
-
- LOGGER.setLevel(Level.INFO);
-
- if(debug_mode){
- LOGGER.info("#######################");
- LOGGER.info("TOKEN:" + token);
- LOGGER.info("ORG:" + orgName);
- LOGGER.info("ENVIRONMENT:" + environment);
- }
-
- String orgId = getOrgId(token, orgName, environment, debug_mode);
- ListBoxModel emptybox = new ListBoxModel();
- emptybox.add("","empty");
-
- if(orgId == null) {
- return emptybox;
- }
-
- CloseableHttpClient httpClient = HttpClients.createDefault();
- String toolchains_url = chooseToolchainsUrl(environment);
- if(debug_mode){
- LOGGER.info("GET TOOLCHAIN LIST URL:" + toolchains_url + orgId);
- }
-
- HttpGet httpGet = new HttpGet(toolchains_url + orgId);
-
- httpGet = addProxyInformation(httpGet);
-
- httpGet.setHeader("Authorization", token);
- CloseableHttpResponse response = null;
-
- try {
- response = httpClient.execute(httpGet);
- String resStr = EntityUtils.toString(response.getEntity());
-
- if(debug_mode){
- LOGGER.info("RESPONSE FROM TOOLCHAINS API:" + response.getStatusLine().toString());
- }
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject obj = element.getAsJsonObject();
- JsonArray items = obj.getAsJsonArray("items");
- ListBoxModel toolchainList = new ListBoxModel();
-
- for (int i = 0; i < items.size(); i++) {
- JsonObject toolchainObj = items.get(i).getAsJsonObject();
- String toolchainName = String.valueOf(toolchainObj.get("name")).replaceAll("\"", "");
- String toolchainID = String.valueOf(toolchainObj.get("toolchain_guid")).replaceAll("\"", "");
- toolchainList.add(toolchainName,toolchainID);
- }
- if(debug_mode){
- LOGGER.info("TOOLCHAIN LIST:" + toolchainList);
- LOGGER.info("#######################");
- }
- if(toolchainList.isEmpty()) {
- if(debug_mode){
- LOGGER.info("RETURNED NO TOOLCHAINS.");
- }
- return emptybox;
- }
- return toolchainList;
- } else {
- LOGGER.info("RETURNED STATUS CODE OTHER THAN 200. RESPONSE: " + response.getStatusLine().toString());
- return emptybox;
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return emptybox;
- }
-
- public static String getOrgId(String token, String orgName, String environment, Boolean debug_mode) {
- CloseableHttpClient httpClient = HttpClients.createDefault();
- String organizations_url = chooseOrganizationsUrl(environment);
- if(debug_mode){
- LOGGER.info("GET ORG_GUID URL:" + organizations_url + orgName);
- }
-
- try {
- HttpGet httpGet = new HttpGet(organizations_url + URLEncoder.encode(orgName, "UTF-8").replaceAll("\\+", "%20"));
-
- httpGet = addProxyInformation(httpGet);
-
- httpGet.setHeader("Authorization", token);
- CloseableHttpResponse response = null;
-
- response = httpClient.execute(httpGet);
- String resStr = EntityUtils.toString(response.getEntity());
-
- if(debug_mode){
- LOGGER.info("RESPONSE FROM ORGANIZATIONS API:" + response.getStatusLine().toString());
- }
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject obj = element.getAsJsonObject();
- JsonArray resources = obj.getAsJsonArray("resources");
-
- if(resources.size() > 0) {
- JsonObject resource = resources.get(0).getAsJsonObject();
- JsonObject metadata = resource.getAsJsonObject("metadata");
- if(debug_mode){
- LOGGER.info("ORG_ID:" + String.valueOf(metadata.get("guid")).replaceAll("\"", ""));
- }
- return String.valueOf(metadata.get("guid")).replaceAll("\"", "");
- }
- else {
- if(debug_mode){
- LOGGER.info("RETURNED NO ORGANIZATIONS.");
- }
- return null;
- }
-
- } else {
- if(debug_mode){
- LOGGER.info("RETURNED STATUS CODE OTHER THAN 200. RESPONSE: " + response.getStatusLine().toString());
- }
- return null;
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- public static String getSpaceId(String token, String spaceName, String environment, Boolean debug_mode) {
- CloseableHttpClient httpClient = HttpClients.createDefault();
- String spaces_url = chooseSpacesUrl(environment);
- if(debug_mode){
- LOGGER.info("GET SPACE_GUID URL:" + spaces_url + spaceName);
- }
-
- try {
- HttpGet httpGet = new HttpGet(spaces_url + URLEncoder.encode(spaceName, "UTF-8").replaceAll("\\+", "%20"));
-
- httpGet = addProxyInformation(httpGet);
-
- httpGet.setHeader("Authorization", token);
- CloseableHttpResponse response = null;
-
- response = httpClient.execute(httpGet);
- String resStr = EntityUtils.toString(response.getEntity());
-
- if(debug_mode){
- LOGGER.info("RESPONSE FROM SPACES API:" + response.getStatusLine().toString());
- }
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject obj = element.getAsJsonObject();
- JsonArray resources = obj.getAsJsonArray("resources");
-
- if(resources.size() > 0) {
- JsonObject resource = resources.get(0).getAsJsonObject();
- JsonObject metadata = resource.getAsJsonObject("metadata");
- if(debug_mode){
- LOGGER.info("SPACE_ID:" + String.valueOf(metadata.get("guid")).replaceAll("\"", ""));
- }
- return String.valueOf(metadata.get("guid")).replaceAll("\"", "");
- }
- else {
- if(debug_mode){
- LOGGER.info("RETURNED NO SPACES.");
- }
- return null;
- }
-
- } else {
- if(debug_mode){
- LOGGER.info("RETURNED STATUS CODE OTHER THAN 200. RESPONSE: " + response.getStatusLine().toString());
- }
- return null;
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- public static String getAppId(String token, String appName, String orgName, String spaceName, String environment, Boolean debug_mode) {
- CloseableHttpClient httpClient = HttpClients.createDefault();
- String apps_url = chooseAppsUrl(environment);
- if(debug_mode){
- LOGGER.info("GET APPS_GUID URL:" + apps_url + appName + ORG + orgName + SPACE + spaceName);
- }
-
- try {
- HttpGet httpGet = new HttpGet(apps_url + URLEncoder.encode(appName, "UTF-8").replaceAll("\\+", "%20") + ORG + URLEncoder.encode(orgName, "UTF-8").replaceAll("\\+", "%20") + SPACE + URLEncoder.encode(spaceName, "UTF-8").replaceAll("\\+", "%20"));
-
- httpGet = addProxyInformation(httpGet);
-
- httpGet.setHeader("Authorization", token);
- CloseableHttpResponse response = null;
-
- response = httpClient.execute(httpGet);
- String resStr = EntityUtils.toString(response.getEntity());
-
- if(debug_mode){
- LOGGER.info("RESPONSE FROM APPS API:" + response.getStatusLine().toString());
- }
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject obj = element.getAsJsonObject();
- JsonArray resources = obj.getAsJsonArray("resources");
-
- if(resources.size() > 0) {
- JsonObject resource = resources.get(0).getAsJsonObject();
- JsonObject metadata = resource.getAsJsonObject("metadata");
- if(debug_mode){
- LOGGER.info("APP_ID:" + String.valueOf(metadata.get("guid")).replaceAll("\"", ""));
- }
- return String.valueOf(metadata.get("guid")).replaceAll("\"", "");
- }
- else {
- if(debug_mode){
- LOGGER.info("RETURNED NO APPS.");
- }
- return null;
- }
-
- } else {
- if(debug_mode){
- LOGGER.info("RETURNED STATUS CODE OTHER THAN 200. RESPONSE: " + response.getStatusLine().toString());
- }
- return null;
- }
-
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- /**
- * Get a list of policies that belong to an org
- * @param token
- * @param orgName
- * @return
- */
-
- public static ListBoxModel getPolicyList(String token, String orgName, String toolchainName, String environment, Boolean debug_mode) {
-
- // get all jenkins job
- ListBoxModel emptybox = new ListBoxModel();
- emptybox.add("","empty");
-
- String url = choosePoliciesUrl(environment);
-
-
- try {
- url = url.replace("{org_name}", URLEncoder.encode(orgName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{toolchain_name}", URLEncoder.encode(toolchainName, "UTF-8").replaceAll("\\+", "%20"));
- if(debug_mode){
- LOGGER.info("GET POLICIES URL:" + url);
- }
-
- CloseableHttpClient httpClient = HttpClients.createDefault();
- HttpGet httpGet = new HttpGet(url);
-
- httpGet = addProxyInformation(httpGet);
-
- httpGet.setHeader("Authorization", token);
- CloseableHttpResponse response = null;
- response = httpClient.execute(httpGet);
- String resStr = EntityUtils.toString(response.getEntity());
-
- if(debug_mode){
- LOGGER.info("RESPONSE FROM GET POLICIES URL:" + response.getStatusLine().toString());
- }
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonArray jsonArray = element.getAsJsonArray();
-
- ListBoxModel model = new ListBoxModel();
-
- for (int i = 0; i < jsonArray.size(); i++) {
- JsonObject obj = jsonArray.get(i).getAsJsonObject();
- String name = String.valueOf(obj.get("name")).replaceAll("\"", "");
- model.add(name, name);
- }
- if(debug_mode){
- LOGGER.info("POLICY LIST:" + model);
- LOGGER.info("#######################");
- }
- return model;
- } else {
- if(debug_mode){
- LOGGER.info("RETURNED STATUS CODE OTHER THAN 200. RESPONSE: " + response.getStatusLine().toString());
- }
- return emptybox;
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return emptybox;
- }
-
- /**
- * write to the environment variables to pass to next build step
- * @param build - the current build
- * @param bluemixToken - the Bluemix Token
- * @param buildId - the build number of the build job in the Jenkins
- */
- public static void passEnvToNextBuildStep (Run build, final String bluemixToken, final String buildId) {
-
- build.addAction(new EnvironmentContributingAction() {
- @Override
- public String getIconFileName() {
- return null;
- }
-
- @Override
- public String getDisplayName() {
- return null;
- }
-
- @Override
- public String getUrlName() {
- return null;
- }
-
- public void buildEnvVars(AbstractBuild, ?> build, EnvVars envVars) {
- if (envVars != null) {
- if (!Util.isNullOrEmpty(bluemixToken)) {
- envVars.put("DI_BM_TOKEN", bluemixToken);
- }
-
- if (!Util.isNullOrEmpty(buildId)) {
- envVars.put("DI_BUILD_ID", buildId);
- }
- }
- }
- }
- );
- }
-
- public static HttpGet addProxyInformation (HttpGet instance) {
- /* Add proxy to request if proxy settings in Jenkins UI are set. */
- ProxyConfiguration proxyConfig = Jenkins.getInstance().proxy;
- if(proxyConfig != null){
- if((!Util.isNullOrEmpty(proxyConfig.name)) && proxyConfig.port != 0) {
- HttpHost proxy = new HttpHost(proxyConfig.name, proxyConfig.port, "http");
- RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
- instance.setConfig(config);
- }
- }
- return instance;
- }
-
- public static HttpPost addProxyInformation (HttpPost instance) {
- /* Add proxy to request if proxy settings in Jenkins UI are set. */
- ProxyConfiguration proxyConfig = Jenkins.getInstance().proxy;
- if(proxyConfig != null){
- if((!Util.isNullOrEmpty(proxyConfig.name)) && proxyConfig.port != 0) {
- HttpHost proxy = new HttpHost(proxyConfig.name, proxyConfig.port, "http");
- RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
- instance.setConfig(config);
- }
- }
- return instance;
- }
-
-}
diff --git a/src/main/java/com/ibm/devops/dra/AbstractGateAction.java b/src/main/java/com/ibm/devops/dra/AbstractGateAction.java
deleted file mode 100644
index 702aeab..0000000
--- a/src/main/java/com/ibm/devops/dra/AbstractGateAction.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import hudson.model.AbstractBuild;
-import hudson.model.Action;
-
-/**
- * Abstract Decision Text Action
- */
-public abstract class AbstractGateAction implements Action {
- public abstract Boolean getShowHeader();
-
- public abstract String getText();
-
- public abstract AbstractBuild, ?> getBuild();
-
- @Override
- public String getIconFileName() {
- return null;
- }
-
- @Override
- public String getDisplayName() {
- return null;
- }
-
- @Override
- public String getUrlName() {
- return null;
- }
-
-}
diff --git a/src/main/java/com/ibm/devops/dra/BuildInfoModel.java b/src/main/java/com/ibm/devops/dra/BuildInfoModel.java
deleted file mode 100644
index 58fc40f..0000000
--- a/src/main/java/com/ibm/devops/dra/BuildInfoModel.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-public class BuildInfoModel {
- private String build_id;
- private String job_url;
- private String status;
- private String timestamp;
- private Repo repository;
-
- public BuildInfoModel(String build_id, String job_url, String status, String timestamp, Repo repository) {
- this.build_id = build_id;
- this.job_url = job_url;
- this.status = status;
- this.timestamp = timestamp;
- this.repository = repository;
- }
-
- public String getBuild_id() {
- return build_id;
- }
-
- public String getJob_url() {
- return job_url;
- }
-
- public String getStatus() {
- return status;
- }
-
- public String getTimestamp() {
- return timestamp;
- }
-
- public Repo getRepository() {
- return repository;
- }
-
- public static class Repo {
- private String repository_url;
- private String branch;
- private String commit_id;
-
- public Repo(String repository_url, String branch, String commit_id) {
- this.repository_url = repository_url;
- this.branch = branch;
- this.commit_id = commit_id;
- }
-
- public String getRepository_url() {
- return repository_url;
- }
-
- public String getBranch() {
- return branch;
- }
-
- public String getCommit_id() {
- return commit_id;
- }
- }
-
-
-}
diff --git a/src/main/java/com/ibm/devops/dra/BuildPublisherAction.java b/src/main/java/com/ibm/devops/dra/BuildPublisherAction.java
deleted file mode 100644
index 6f20075..0000000
--- a/src/main/java/com/ibm/devops/dra/BuildPublisherAction.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import hudson.model.Action;
-
-public class BuildPublisherAction implements Action {
-
- private final String link;
-
- public BuildPublisherAction(String link) {
- this.link = link;
- }
-
- public String getLink() {
- return link;
- }
-
- @Override
- public String getIconFileName() {
- return null;
- }
-
- @Override
- public String getDisplayName() {
- return null;
- }
-
- @Override
- public String getUrlName() {
- return null;
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/DeploymentInfoModel.java b/src/main/java/com/ibm/devops/dra/DeploymentInfoModel.java
deleted file mode 100644
index e4aacc2..0000000
--- a/src/main/java/com/ibm/devops/dra/DeploymentInfoModel.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-public class DeploymentInfoModel {
- private String app_url;
- private String environment_name;
- private String job_url;
- private String status;
- private String timestamp;
-
- public DeploymentInfoModel(String app_url, String environment_name, String job_url, String status, String timestamp) {
- this.app_url = app_url;
- this.environment_name = environment_name;
- this.job_url = job_url;
- this.status = status;
- this.timestamp = timestamp;
- }
-
- public String getApp_url() {
- return app_url;
- }
-
- public String getEnvironment_name() {
- return environment_name;
- }
-
- public String getJob_url() {
- return job_url;
- }
-
- public String getStatus() {
- return status;
- }
-
- public String getTimestamp() {
- return timestamp;
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/DevOpsGlobalConfiguration.java b/src/main/java/com/ibm/devops/dra/DevOpsGlobalConfiguration.java
deleted file mode 100644
index ce44b7c..0000000
--- a/src/main/java/com/ibm/devops/dra/DevOpsGlobalConfiguration.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import hudson.CopyOnWrite;
-import hudson.Extension;
-import hudson.util.ListBoxModel;
-import jenkins.model.GlobalConfiguration;
-import net.sf.json.JSONObject;
-import org.kohsuke.stapler.StaplerRequest;
-
-/**
- * Created by lix on 7/20/17.
- */
-@Extension(ordinal = 100)
-public class DevOpsGlobalConfiguration extends GlobalConfiguration {
-
- @CopyOnWrite
- private volatile String consoleUrl;
- private volatile boolean debug_mode;
-
- public DevOpsGlobalConfiguration() {
- load();
- }
-
- public String getConsoleUrl() {
- return consoleUrl;
- }
-
- public boolean isDebug_mode() {
- return debug_mode;
- }
-
- public void setDebug_mode(boolean debug_mode) {
- this.debug_mode = debug_mode;
- save();
- }
-
- public void setConsoleUrl(String consoleUrl) {
- this.consoleUrl = consoleUrl;
- save();
- }
-
- @Override
- public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
- // To persist global configuration information,
- // set that to properties and call save().
- consoleUrl = formData.getString("consoleUrl");
- debug_mode = Boolean.parseBoolean(formData.getString("debug_mode"));
- save();
- return super.configure(req,formData);
- }
-
- // for the future multi-region use
- public ListBoxModel doFillRegionItems() {
- ListBoxModel items = new ListBoxModel();
- return items;
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/EnvironmentScope.java b/src/main/java/com/ibm/devops/dra/EnvironmentScope.java
deleted file mode 100644
index e92d190..0000000
--- a/src/main/java/com/ibm/devops/dra/EnvironmentScope.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import hudson.Extension;
-import hudson.model.AbstractDescribableImpl;
-import hudson.model.Descriptor;
-import org.kohsuke.stapler.DataBoundConstructor;
-
-public class EnvironmentScope extends AbstractDescribableImpl {
- private boolean isBuild;
- private boolean isAll;
- private boolean isDeploy;
- private String branchName;
- private String envName;
-
- @DataBoundConstructor
- public EnvironmentScope(String value, String branchName, String envName) {
- switch (value) {
- case "build":
- this.isBuild = true;
- this.isDeploy = false;
- this.isAll = false;
- break;
- case "deploy":
- this.isDeploy = true;
- this.isBuild = false;
- this.isAll = false;
- break;
- default:
- this.isAll = true;
- this.isBuild = false;
- this.isDeploy = false;
- break;
- }
-
- this.branchName = branchName;
- this.envName = envName;
- }
-
- public boolean isBuild() {
- return isBuild;
- }
-
- public boolean isAll() {
- return isAll;
- }
-
- public boolean isDeploy() {
- return isDeploy;
- }
-
- public String getBranchName() {
- return branchName;
- }
-
- public void setBranchName(String branchName) {
- this.branchName = branchName;
- }
-
- public String getEnvName() {
- return envName;
- }
-
- public void setEnvName(String envName) {
- this.envName = envName;
- }
-
-
- @Extension
- public static class DescriptorImpl extends Descriptor {
- @Override
- public String getDisplayName() {
- return "DevOps Insight Test Environment Scope";
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/EvaluateGate.java b/src/main/java/com/ibm/devops/dra/EvaluateGate.java
deleted file mode 100644
index d4a23ce..0000000
--- a/src/main/java/com/ibm/devops/dra/EvaluateGate.java
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import com.cloudbees.plugins.credentials.CredentialsMatchers;
-import com.cloudbees.plugins.credentials.CredentialsProvider;
-import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
-import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
-import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
-import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSyntaxException;
-import hudson.*;
-import hudson.model.*;
-import hudson.security.ACL;
-import hudson.tasks.BuildStepDescriptor;
-import hudson.tasks.BuildStepMonitor;
-import hudson.tasks.Publisher;
-import hudson.util.FormValidation;
-import hudson.util.ListBoxModel;
-import jenkins.model.Jenkins;
-import jenkins.tasks.SimpleBuildStep;
-import net.sf.json.JSONObject;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.kohsuke.stapler.AncestorInPath;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.QueryParameter;
-import org.kohsuke.stapler.StaplerRequest;
-
-import javax.annotation.Nonnull;
-import javax.servlet.ServletException;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.net.URLEncoder;
-import java.util.HashMap;
-import java.util.List;
-
-
-/**
- * Customized build step to get a gate decision from DRA backend
- */
-
-public class EvaluateGate extends AbstractDevOpsAction implements SimpleBuildStep{
-
- private final static String CONTENT_TYPE = "application/json";
-
- // form fields from UI
- private final String policyName;
- private String orgName;
- private String buildJobName;
- private String applicationName;
- private String toolchainName;
- private String environmentName;
- private String credentialsId;
- private boolean willDisrupt;
-
- private EnvironmentScope scope;
- private String envName;
- private boolean isDeploy;
-
- private String draUrl;
- private PrintStream printStream;
- private static String bluemixToken;
- private static String preCredentials;
-
- //fields to support jenkins pipeline
- private String username;
- private String password;
- // optional customized build number
- private String buildNumber;
-
- // Fields in config.jelly must match the parameter names in the "DataBoundConstructor"
- @DataBoundConstructor
- public EvaluateGate(String policyName,
- String orgName,
- String applicationName,
- String toolchainName,
- String environmentName,
- String buildJobName,
- String credentialsId,
- boolean willDisrupt,
- EnvironmentScope scope,
- OptionalBuildInfo additionalBuildInfo) {
- this.policyName = policyName;
- this.orgName = orgName;
- this.applicationName = applicationName;
- this.toolchainName = toolchainName;
- this.environmentName = environmentName;
- this.buildJobName = buildJobName;
- this.credentialsId = credentialsId;
- this.willDisrupt = willDisrupt;
- this.scope = scope;
- this.envName = scope.getEnvName();
- this.isDeploy = scope.isDeploy();
- if (additionalBuildInfo == null) {
- this.buildNumber = null;
- } else {
- this.buildNumber = additionalBuildInfo.buildNumber;
- }
- }
-
- public EvaluateGate(HashMap envVarsMap,
- String policyName,
- String environmentName,
- boolean willDisrupt) {
-
- this.applicationName = envVarsMap.get(APP_NAME);
- this.orgName = envVarsMap.get(ORG_NAME);
- this.toolchainName = envVarsMap.get(TOOLCHAIN_ID);
- this.username = envVarsMap.get(USERNAME);
- this.password = envVarsMap.get(PASSWORD);
- this.envName = environmentName;
- this.willDisrupt = willDisrupt;
- this.policyName = policyName;
- }
-
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- /**
- * We'll use this from the config.jelly.
- */
-
- public String getPolicyName() {
- return policyName;
- }
-
- public String getOrgName() {
- return orgName;
- }
-
- public String getBuildJobName() {
- return buildJobName;
- }
-
- public String getApplicationName() {
- return applicationName;
- }
-
- public String getToolchainName() {
- return toolchainName;
- }
-
- public String getEnvironmentName() {
- return environmentName;
- }
-
- public String getCredentialsId() {
- return credentialsId;
- }
-
- public boolean isWillDisrupt() {
- return willDisrupt;
- }
-
- public EnvironmentScope getScope() {
- return scope;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public String getEnvName() {
- return envName;
- }
-
- public boolean isDeploy() {
- return isDeploy;
- }
-
- public static class OptionalBuildInfo {
- private String buildNumber;
-
- @DataBoundConstructor
- public OptionalBuildInfo(String buildNumber, String buildUrl) {
- this.buildNumber = buildNumber;
- }
- }
-
- /**
- * Override this method to get your operation done in the build step. When invoked, it is up to you, as a plugin developer
- * to add your actions, and/or perform the operations required by your plugin in this build step. Equally, it is up
- * to the developer to make the code run on the slave(master or an actual remote). This must be done given the builds
- * workspace, as in build.getWorkspace(). The workspace is the link to the slave, as it is the representation of the
- * remote file system.
- *
- * Build steps as you add them to your job configuration are executed sequentially, and the return value for your
- * builder should indicate whether to execute the next build step in the list.
- * @param build - the current build
- * @param launcher - the launcher
- * @param listener - the build listener
- * @throws InterruptedException
- * @throws IOException
- */
- @Override
- public void perform(@Nonnull Run, ?> build, @Nonnull FilePath filePath, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException {
- // This is where you 'build' the project.
- printStream = listener.getLogger();
- printPluginVersion(this.getClass().getClassLoader(), printStream);
-
- // Get the project name and build id from environment
- EnvVars envVars = build.getEnvironment(listener);
- this.orgName = envVars.expand(this.orgName);
- this.applicationName = envVars.expand(this.applicationName);
- this.toolchainName = envVars.expand(this.toolchainName);
-
- if (this.isDeploy || !Util.isNullOrEmpty(this.envName)) {
- this.environmentName = envVars.expand(this.envName);
- }
-
- // verify if user chooses advanced option to input customized DRA
- String env = getDescriptor().getEnvironment();
- this.draUrl = chooseDRAUrl(env);
- String targetAPI = chooseTargetAPI(env);
-
- String buildNumber;
- if (Util.isNullOrEmpty(this.buildNumber)) {
- // locate the build job that triggers current build
- Run triggeredBuild = getTriggeredBuild(build, buildJobName, envVars, printStream);
- if (triggeredBuild == null) {
- //failed to find the build job
- return;
- } else {
- if (Util.isNullOrEmpty(this.buildJobName)) {
- // handle the case which the build job name left empty, and the pipeline case
- this.buildJobName = envVars.get("JOB_NAME");
- }
- buildNumber = getBuildNumber(buildJobName, triggeredBuild);
- }
- } else {
- buildNumber = envVars.expand(this.buildNumber);
- }
-
- String bluemixToken;
- // get the Bluemix token
- try {
- if (Util.isNullOrEmpty(this.credentialsId)) {
- bluemixToken = getBluemixToken(username, password, targetAPI);
- } else {
- bluemixToken = getBluemixToken(build.getParent(), this.credentialsId, targetAPI);
- }
-
- printStream.println("[IBM Cloud DevOps] Log in successfully, get the Bluemix token");
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Username/Password is not correct, fail to authenticate with Bluemix");
- printStream.println("[IBM Cloud DevOps]" + e.toString());
- return;
- }
-
- // get decision response from DRA
- try {
- JsonObject decisionJson = getDecisionFromDRA(bluemixToken, buildNumber);
- if (decisionJson == null) {
- printStream.println("[IBM Cloud DevOps] get empty decision");
- return;
- }
-
- // retrieve the decision id to compose the report link
- String decisionId = String.valueOf(decisionJson.get("decision_id"));
- // remove the double quotes
- decisionId = decisionId.replace("\"","");
-
- // Show Proceed or Failed based on the decision
- String decision = String.valueOf(decisionJson.get("contents").getAsJsonObject().get("proceed"));
- if (decision.equals("true")) {
- decision = "Succeed";
- } else {
- decision = "Failed";
- }
-
- String cclink = chooseControlCenterUrl(env) + "deploymentrisk?orgName=" + URLEncoder.encode(this.orgName, "UTF-8") + "&toolchainId=" + this.toolchainName;
- String reportUrl = chooseControlCenterUrl(env) + "decisionreport?orgName=" + URLEncoder.encode(this.orgName, "UTF-8") + "&toolchainId="
- + URLEncoder.encode(toolchainName, "UTF-8") + "&reportId=" + decisionId;
-
- GatePublisherAction action = new GatePublisherAction(reportUrl, cclink, decision, this.policyName, build);
- build.addAction(action);
-
- printStream.println("************************************");
- printStream.println("Check IBM Cloud DevOps Gate Evaluation report here -" + reportUrl);
- // console output for a "fail" decision
- if (decision.equals("Failed")) {
- printStream.println("IBM Cloud DevOps decision to proceed is: false");
- printStream.println("************************************");
- if (willDisrupt) {
- Result result = Result.FAILURE;
- build.setResult(result);
- throw new AbortException("Decision is fail");
- }
- return;
- }
-
- // console output for a "proceed" decision
- printStream.println("IBM Cloud DevOps decision to proceed is: true");
- printStream.println("************************************");
- return;
-
- } catch (IOException e) {
- if (e instanceof AbortException) {
- throw new AbortException("Decision is fail");
- } else {
- printStream.print("[IBM Cloud DevOps] Error: " + e.getMessage());
- }
- }
- }
-
- @Override
- public BuildStepMonitor getRequiredMonitorService() {
- return BuildStepMonitor.NONE;
- }
-
- /**
- * Send a request to DRA backend to get a decision
- * @param buildId - build ID, get from Jenkins environment
- * @return - the response decision Json file
- */
- private JsonObject getDecisionFromDRA(String bluemixToken, String buildId) throws IOException {
- // create http client and post method
- CloseableHttpClient httpClient = HttpClients.createDefault();
- String url = this.draUrl;
- url = url + "/organizations/" + URLEncoder.encode(orgName, "UTF-8").replaceAll("\\+", "%20") +
- "/toolchainids/" + URLEncoder.encode(toolchainName, "UTF-8").replaceAll("\\+", "%20") +
- "/buildartifacts/" + URLEncoder.encode(applicationName, "UTF-8").replaceAll("\\+", "%20") +
- "/builds/" + URLEncoder.encode(buildId, "UTF-8").replaceAll("\\+", "%20") +
- "/policies/" + URLEncoder.encode(policyName, "UTF-8").replaceAll("\\+", "%20") +
- "/decisions";
- if (!Util.isNullOrEmpty(this.environmentName)) {
- url = url.concat("?environment_name=" + environmentName);
- }
-
- HttpPost postMethod = new HttpPost(url);
-
- postMethod = addProxyInformation(postMethod);
- postMethod.setHeader("Authorization", bluemixToken);
- postMethod.setHeader("Content-Type", CONTENT_TYPE);
-
- CloseableHttpResponse response = httpClient.execute(postMethod);
- String resStr = EntityUtils.toString(response.getEntity());
-
- try {
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject resJson = element.getAsJsonObject();
- printStream.println("[IBM Cloud DevOps] Get decision successfully");
- return resJson;
- } else {
- // if gets error status
- printStream.println("[IBM Cloud DevOps] Error: Failed to get a decision, response status " + response.getStatusLine());
-
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject resJson = element.getAsJsonObject();
- if (resJson != null && resJson.has("message")) {
- printStream.println("[IBM Cloud DevOps] Reason: " + resJson.get("message"));
- }
- }
- } catch (JsonSyntaxException e) {
- printStream.println("[IBM Cloud DevOps] Invalid Json response, response: " + resStr);
- }
-
- return null;
- }
-
-
- @Override
- public EvaluateGateImpl getDescriptor() {
- return (EvaluateGateImpl)super.getDescriptor();
- }
-
- /**
- * Descriptor for {@link EvaluateGate}. Used as a singleton.
- * The class is marked as public so that it can be accessed from views.
- *
- *
- * See src/main/resources/hudson/plugins/hello_world/HelloWorldBuilder/*.jelly
- * for the actual HTML fragment for the configuration screen.
- */
- @Extension // This indicates to Jenkins that this is an implementation of an extension point.
- public static final class EvaluateGateImpl extends BuildStepDescriptor {
-
- /**
- * In order to load the persisted global configuration, you have to
- * call load() in the constructor.
- */
- public EvaluateGateImpl() {
- load();
- }
-
- /**
- * Performs on-the-fly validation of the form field 'name'.
- *
- * @param value
- * This parameter receives the value that the user has typed.
- * @return
- * Indicates the outcome of the validation. This is sent to the browser.
- *
- * Note that returning {@link FormValidation#error(String)} does not
- * prevent the form from being saved. It just means that a message
- * will be displayed to the user.
- */
- public FormValidation doCheckOrgName(@QueryParameter String value)
- throws IOException, ServletException {
-
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckApplicationName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckEnvironmentName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckToolchainName(@QueryParameter String value)
- throws IOException, ServletException {
- if (value == null || value.equals("empty")) {
- return FormValidation.errorWithMarkup("Could not retrieve list of toolchains. Please check your username and password. If you have not created a toolchain, create one here.");
- }
- return FormValidation.ok();
- }
-
- public FormValidation doCheckPolicyName(@QueryParameter String value)
- throws IOException, ServletException {
- if (value == null || value.equals("empty")) {
- return FormValidation.errorWithMarkup("Fail to get the policies, please check your username/password or org name and make sure you have created policies for this org and toolchain.");
- }
- return FormValidation.ok();
- }
-
- public FormValidation doTestConnection(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- if (!credentialsId.equals(preCredentials) || Util.isNullOrEmpty(bluemixToken)) {
- preCredentials = credentialsId;
- try {
- String bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- if (Util.isNullOrEmpty(bluemixToken)) {
- EvaluateGate.bluemixToken = bluemixToken;
- return FormValidation.warning("Got empty token");
- } else {
- return FormValidation.okWithMarkup("Connection successful");
- }
- } catch (Exception e) {
- return FormValidation.error("Failed to log in to Bluemix, please check your username/password");
- }
- } else {
-
- return FormValidation.okWithMarkup("Connection successful");
- }
- }
-
- /**
- * This method is called to populate the credentials list on the Jenkins config page.
- */
- public ListBoxModel doFillCredentialsIdItems(@AncestorInPath ItemGroup context,
- @QueryParameter("target") final String target) {
- StandardListBoxModel result = new StandardListBoxModel();
- result.includeEmptyValue();
- result.withMatching(CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class),
- CredentialsProvider.lookupCredentials(
- StandardUsernameCredentials.class,
- context,
- ACL.SYSTEM,
- URIRequirementBuilder.fromUri(target).build()
- )
- );
- return result;
- }
-
- /**
- * Autocompletion for build job name field
- * @param value
- * @return
- */
- public AutoCompletionCandidates doAutoCompleteBuildJobName(@QueryParameter String value) {
- AutoCompletionCandidates auto = new AutoCompletionCandidates();
-
- // get all jenkins job
- List jobs = Jenkins.getInstance().getAllItems(Job.class);
- for (int i = 0; i < jobs.size(); i++) {
- String jobName = jobs.get(i).getName();
-
- if (jobName.toLowerCase().startsWith(value.toLowerCase())) {
- auto.add(jobName);
- }
- }
-
- return auto;
- }
-
- /**
- * This method is called to populate the policy list on the Jenkins config page.
- * @param context
- * @param orgName
- * @param credentialsId
- * @return
- */
- public ListBoxModel doFillPolicyNameItems(@AncestorInPath ItemGroup context,
- @QueryParameter final String orgName,
- @QueryParameter final String toolchainName,
- @QueryParameter final String credentialsId) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- try {
- // if user changes to a different credential, need to get a new token
- if (!credentialsId.equals(preCredentials) || Util.isNullOrEmpty(bluemixToken)) {
- bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- preCredentials = credentialsId;
- }
- } catch (Exception e) {
- return new ListBoxModel();
- }
- if(isDebug_mode()){
- LOGGER.info("#######GATE : calling getPolicyList#######");
- }
- return getPolicyList(bluemixToken, orgName, toolchainName, environment, isDebug_mode());
-
- }
-
- /**
- * This method is called to populate the toolchain list on the Jenkins config page.
- * @param context
- * @param orgName
- * @param credentialsId
- * @return
- */
- public ListBoxModel doFillToolchainNameItems(@AncestorInPath ItemGroup context,
- @QueryParameter final String orgName,
- @QueryParameter final String credentialsId) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- try {
- bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- } catch (Exception e) {
- return new ListBoxModel();
- }
- if(isDebug_mode()){
- LOGGER.info("#######GATE : calling getToolchainList#######");
- }
- return getToolchainList(bluemixToken, orgName, environment, isDebug_mode());
- }
-
-
- /**
- * Required Method
- * This is used to determine if this build step is applicable for your chosen project type. (FreeStyle, MultiConfiguration, Maven)
- * Some plugin build steps might be made to be only available to MultiConfiguration projects.
- *
- * @param aClass The current project
- * @return a boolean indicating whether this build step can be chose given the project type
- */
- public boolean isApplicable(Class extends AbstractProject> aClass) {
- // Indicates that this builder can be used with all kinds of project types
- // return FreeStyleProject.class.isAssignableFrom(aClass);
- return true;
- }
-
- /**
- * Required Method
- * @return The text to be displayed when selecting your build in the project
- */
- public String getDisplayName() {
- return "IBM Cloud DevOps Gate";
- }
-
- public String getEnvironment() {
- return getEnv(Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getConsoleUrl());
- }
-
- public boolean isDebug_mode() {
- return Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).isDebug_mode();
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/GatePublisherAction.java b/src/main/java/com/ibm/devops/dra/GatePublisherAction.java
deleted file mode 100644
index d4293e7..0000000
--- a/src/main/java/com/ibm/devops/dra/GatePublisherAction.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import hudson.model.Action;
-import hudson.model.Run;
-
-/**
- * DRA action for builds, show the decision and report link in the build status page
- */
-public class GatePublisherAction implements Action {
-
- private final String text;
- private final String riskDashboardLink;
- private final String decision;
- private final String policyName;
- private final Run, ?> build;
-
- public GatePublisherAction(String text, String riskDashboardLink, String decision, String policyName, Run, ?> build) {
- this.text = text;
- this.riskDashboardLink = riskDashboardLink;
- this.decision = decision;
- this.policyName = policyName;
- this.build = build;
- }
-
- public String getText() {
- return text;
- }
-
- public String getRiskDashboardLink() {
- return riskDashboardLink;
- }
-
- public String getDecision() {
- return decision;
- }
-
- public String getPolicyName() {
- return policyName;
- }
-
- public Run, ?> getBuild() {
- return build;
- }
-
- @Override
- public String getIconFileName() {
- return null;
- }
-
- @Override
- public String getDisplayName() {
- return null;
- }
-
- @Override
- public String getUrlName() {
- return null;
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/PublishBuild.java b/src/main/java/com/ibm/devops/dra/PublishBuild.java
deleted file mode 100644
index 7c2006a..0000000
--- a/src/main/java/com/ibm/devops/dra/PublishBuild.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import com.cloudbees.plugins.credentials.CredentialsMatchers;
-import com.cloudbees.plugins.credentials.CredentialsProvider;
-import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
-import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
-import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
-import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
-import com.google.gson.*;
-import hudson.*;
-import hudson.model.*;
-import hudson.security.ACL;
-import hudson.tasks.BuildStepDescriptor;
-import hudson.tasks.BuildStepMonitor;
-import hudson.tasks.Publisher;
-import hudson.util.FormValidation;
-import hudson.util.ListBoxModel;
-import jenkins.model.Jenkins;
-import jenkins.tasks.SimpleBuildStep;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.kohsuke.stapler.*;
-
-import javax.annotation.Nonnull;
-import javax.servlet.ServletException;
-import java.io.*;
-import java.text.SimpleDateFormat;
-import java.util.HashMap;
-import java.util.TimeZone;
-import java.net.URLEncoder;
-
-public class PublishBuild extends AbstractDevOpsAction implements SimpleBuildStep {
-
- private static String BUILD_API_URL = "/organizations/{org_name}/toolchainids/{toolchain_id}/buildartifacts/{build_artifact}/builds";
- private final static String CONTENT_TYPE_JSON = "application/json";
- private final static String CONTENT_TYPE_XML = "application/xml";
-
- // form fields from UI
- private String applicationName;
- private String orgName;
- private String credentialsId;
- private String toolchainName;
-
- private String dlmsUrl;
- private PrintStream printStream;
- private File root;
- private static String bluemixToken;
- private static String preCredentials;
-
- // fields to support jenkins pipeline
- private String result;
- private String gitRepo;
- private String gitBranch;
- private String gitCommit;
- private String username;
- private String password;
- // optional customized build number
- private String buildNumber;
-
-
- @DataBoundConstructor
- public PublishBuild(String applicationName, String orgName, String credentialsId, String toolchainName, OptionalBuildInfo additionalBuildInfo) {
- this.credentialsId = credentialsId;
- this.applicationName = applicationName;
- this.orgName = orgName;
- this.toolchainName = toolchainName;
- if (additionalBuildInfo == null) {
- this.buildNumber = null;
- } else {
- this.buildNumber = additionalBuildInfo.buildNumber;
- }
- }
-
- public PublishBuild(HashMap envVarsMap, HashMap paramsMap) {
- this.gitRepo = paramsMap.get("gitRepo");
- this.gitBranch = paramsMap.get("gitBranch");
- this.gitCommit = paramsMap.get("gitCommit");
- this.result = paramsMap.get("result");
- this.applicationName = envVarsMap.get(APP_NAME);
- this.orgName = envVarsMap.get(ORG_NAME);
- this.toolchainName = envVarsMap.get(TOOLCHAIN_ID);
- this.username = envVarsMap.get(USERNAME);
- this.password = envVarsMap.get(PASSWORD);
- }
-
- @DataBoundSetter
- public void setApplicationName(String applicationName) {
- this.applicationName = applicationName;
- }
-
- @DataBoundSetter
- public void setOrgName(String orgName) {
- this.orgName = orgName;
- }
-
- @DataBoundSetter
- public void setCredentialsId(String credentialsId) {
- this.credentialsId = credentialsId;
- }
-
- @DataBoundSetter
- public void setToolchainName(String toolchainName) {
- this.toolchainName = toolchainName;
- }
-
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- /**
- * We'll use this from the config.jelly.
- */
- public String getApplicationName() {
- return applicationName;
- }
-
- public String getOrgName() {
- return orgName;
- }
-
- public String getCredentialsId() {
- return credentialsId;
- }
-
- public String getToolchainName() {
- return toolchainName;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public static class OptionalBuildInfo {
- private String buildNumber;
-
- @DataBoundConstructor
- public OptionalBuildInfo(String buildNumber, String buildUrl) {
- this.buildNumber = buildNumber;
- }
- }
-
- @Override
- public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException {
-
- printStream = listener.getLogger();
- printPluginVersion(this.getClass().getClassLoader(), printStream);
-
- // create root dir for storing test result
- root = new File(build.getRootDir(), "DRA_TestResults");
-
- // Get the project name and build id from environment
- EnvVars envVars = build.getEnvironment(listener);
-
- // verify if user chooses advanced option to input customized DLMS
- String env = getDescriptor().getEnvironment();
- this.dlmsUrl = chooseDLMSUrl(env) + BUILD_API_URL;
- String targetAPI = chooseTargetAPI(env);
-
- //expand the variables
- this.orgName = envVars.expand(this.orgName);
- this.applicationName = envVars.expand(this.applicationName);
- this.toolchainName = envVars.expand(this.toolchainName);
-
- // Check required parameters
- if (Util.isNullOrEmpty(orgName) || Util.isNullOrEmpty(applicationName) || Util.isNullOrEmpty(toolchainName)) {
- printStream.println("[IBM Cloud DevOps] Missing few required configurations");
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Build Info.");
- return;
- }
-
- String bluemixToken;
- // get the Bluemix token
- try {
- if (Util.isNullOrEmpty(this.credentialsId)) {
- bluemixToken = getBluemixToken(username, password, targetAPI);
- } else {
- bluemixToken = getBluemixToken(build.getParent(), this.credentialsId, targetAPI);
- }
-
- printStream.println("[IBM Cloud DevOps] Log in successfully, get the Bluemix token");
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Username/Password is not correct, fail to authenticate with Bluemix");
- printStream.println("[IBM Cloud DevOps]" + e.toString());
- return;
- }
-
- String link = chooseControlCenterUrl(env) + "deploymentrisk?orgName=" + URLEncoder.encode(this.orgName, "UTF-8") + "&toolchainId=" + this.toolchainName;
- if (uploadBuildInfo(bluemixToken, build, envVars)) {
- printStream.println("[IBM Cloud DevOps] Go to Control Center (" + link + ") to check your build status");
- BuildPublisherAction action = new BuildPublisherAction(link);
- build.addAction(action);
- }
- }
-
- /**
- * Construct the Git data model
- * @param envVars
- * @return
- */
- public BuildInfoModel.Repo buildGitRepo(EnvVars envVars) {
- String repoUrl = envVars.get("GIT_URL");
- String branch = envVars.get("GIT_BRANCH");
- String commitId = envVars.get("GIT_COMMIT");
-
- repoUrl = Util.isNullOrEmpty(repoUrl) ? this.gitRepo : repoUrl;
- branch = Util.isNullOrEmpty(branch) ? this.gitBranch : branch;
- commitId = Util.isNullOrEmpty(commitId) ? this.gitCommit : commitId;
- if (!Util.isNullOrEmpty(branch)) {
- String[] parts = branch.split("/");
- branch = parts[parts.length - 1];
- }
-
- BuildInfoModel.Repo repo = new BuildInfoModel.Repo(repoUrl, branch, commitId);
- return repo;
- }
-
- /**
- * Upload the build information to DLMS - API V2.
- * @param bluemixToken
- * @param build
- * @param envVars
- * @throws IOException
- */
- private boolean uploadBuildInfo(String bluemixToken, Run build, EnvVars envVars) {
- String resStr = "";
-
- try {
- CloseableHttpClient httpClient = HttpClients.createDefault();
- String url = this.dlmsUrl;
- url = url.replace("{org_name}", URLEncoder.encode(this.orgName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{toolchain_id}", URLEncoder.encode(this.toolchainName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{build_artifact}", URLEncoder.encode(this.applicationName, "UTF-8").replaceAll("\\+", "%20"));
-
- String buildNumber;
- if (Util.isNullOrEmpty(this.buildNumber)) {
- buildNumber = getBuildNumber(envVars.get("JOB_NAME"), build);
- } else {
- buildNumber = envVars.expand(this.buildNumber);
- }
-
- String buildUrl;
- if (checkRootUrl(printStream)) {
- buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
- } else {
- buildUrl = build.getAbsoluteUrl();
- }
- HttpPost postMethod = new HttpPost(url);
- postMethod = addProxyInformation(postMethod);
- postMethod.setHeader("Authorization", bluemixToken);
- postMethod.setHeader("Content-Type", CONTENT_TYPE_JSON);
-
- String buildStatus;
- Result result = build.getResult();
- if ((result != null && result.equals(Result.SUCCESS))
- || (this.result != null && this.result.equals(RESULT_SUCCESS))) {
- buildStatus = "pass";
- } else {
- buildStatus = "fail";
- }
-
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
- TimeZone utc = TimeZone.getTimeZone("UTC");
- dateFormat.setTimeZone(utc);
- String timestamp = dateFormat.format(System.currentTimeMillis());
-
- // build up the json body
- Gson gson = new Gson();
- BuildInfoModel.Repo repo = buildGitRepo(envVars);
- BuildInfoModel buildInfo = new BuildInfoModel(buildNumber, buildUrl, buildStatus, timestamp, repo);
-
- String json = gson.toJson(buildInfo);
- StringEntity data = new StringEntity(json);
- postMethod.setEntity(data);
- CloseableHttpResponse response = httpClient.execute(postMethod);
- resStr = EntityUtils.toString(response.getEntity());
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- printStream.println("[IBM Cloud DevOps] Upload Build Information successfully");
- return true;
-
- } else {
- // if gets error status
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload, response status " + response.getStatusLine());
-
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject resJson = element.getAsJsonObject();
- if (resJson != null && resJson.has("user_error")) {
- printStream.println("[IBM Cloud DevOps] Reason: " + resJson.get("user_error"));
- }
- }
- } catch (JsonSyntaxException e) {
- printStream.println("[IBM Cloud DevOps] Invalid Json response, response: " + resStr);
- } catch (IllegalStateException e) {
- // will be triggered when 403 Forbidden
- try {
- printStream.println("[IBM Cloud DevOps] Please check if you have the access to " + URLEncoder.encode(this.orgName, "UTF-8") + " org");
- } catch (UnsupportedEncodingException e1) {
- e1.printStackTrace();
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return false;
- }
-
- @Override
- public BuildStepMonitor getRequiredMonitorService() {
- return BuildStepMonitor.NONE;
- }
-
-
- // Overridden for better type safety.
- // If your plugin doesn't really define any property on Descriptor,
- // you don't have to do this.
- @Override
- public PublishBuildActionImpl getDescriptor() {
- return (PublishBuildActionImpl)super.getDescriptor();
- }
-
- /**
- * Descriptor for {@link PublishBuild}. Used as a singleton.
- * The class is marked as public so that it can be accessed from views.
- *
- *
- * See src/main/resources/com/ibm/devops/dra/PublishBuild/*.jelly
- * for the actual HTML fragment for the configuration screen.
- */
- @Extension // This indicates to Jenkins that this is an implementation of an extension point.
- public static final class PublishBuildActionImpl extends BuildStepDescriptor {
- /**
- * To persist global configuration information,
- * simply store it in a field and call save().
- *
- *
- * If you don't want fields to be persisted, use transient.
- */
-
- /**
- * In order to load the persisted global configuration, you have to
- * call load() in the constructor.
- */
- public PublishBuildActionImpl() {
- super(PublishBuild.class);
- load();
- }
-
- /**
- * Performs on-the-fly validation of the form field 'credentialId'.
- *
- * @param value
- * This parameter receives the value that the user has typed.
- * @return
- * Indicates the outcome of the validation. This is sent to the browser.
- *
- * Note that returning {@link FormValidation#error(String)} does not
- * prevent the form from being saved. It just means that a message
- * will be displayed to the user.
- */
-
- public FormValidation doCheckOrgName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckToolchainName(@QueryParameter String value)
- throws IOException, ServletException {
- if (value == null || value.equals("empty")) {
- return FormValidation.errorWithMarkup("Could not retrieve list of toolchains. Please check your username and password. If you have not created a toolchain, create one here.");
- }
- return FormValidation.ok();
- }
-
- public FormValidation doCheckApplicationName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckEnvironmentName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doTestConnection(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- if (!credentialsId.equals(preCredentials) || Util.isNullOrEmpty(bluemixToken)) {
- preCredentials = credentialsId;
- try {
- String newToken = getBluemixToken(context, credentialsId, targetAPI);
- if (Util.isNullOrEmpty(newToken)) {
- bluemixToken = newToken;
- return FormValidation.warning("Got empty token");
- } else {
- return FormValidation.okWithMarkup("Connection successful");
- }
- } catch (Exception e) {
- return FormValidation.error("Failed to log in to Bluemix, please check your username/password");
- }
- } else {
- return FormValidation.okWithMarkup("Connection successful");
- }
- }
-
- /**
- * This method is called to populate the credentials list on the Jenkins config page.
- */
- public ListBoxModel doFillCredentialsIdItems(@AncestorInPath ItemGroup context,
- @QueryParameter("target") final String target) {
- StandardListBoxModel result = new StandardListBoxModel();
- result.includeEmptyValue();
- result.withMatching(CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class),
- CredentialsProvider.lookupCredentials(
- StandardUsernameCredentials.class,
- context,
- ACL.SYSTEM,
- URIRequirementBuilder.fromUri(target).build()
- )
- );
- return result;
- }
-
- /**
- * This method is called to populate the toolchain list on the Jenkins config page.
- * @param context
- * @param orgName
- * @param credentialsId
- * @return
- */
- public ListBoxModel doFillToolchainNameItems(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId,
- @QueryParameter("orgName") final String orgName) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- try {
- bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- } catch (Exception e) {
- return new ListBoxModel();
- }
- if(isDebug_mode()){
- LOGGER.info("#######UPLOAD BUILD INFO : calling getToolchainList#######");
- }
- ListBoxModel toolChainListBox = getToolchainList(bluemixToken, orgName, environment, isDebug_mode());
- return toolChainListBox;
-
- }
-
- /**
- * Required Method
- * This is used to determine if this build step is applicable for your chosen project type. (FreeStyle, MultiConfiguration, Maven)
- * Some plugin build steps might be made to be only available to MultiConfiguration projects.
- *
- * @param aClass The current project
- * @return a boolean indicating whether this build step can be chose given the project type
- */
- public boolean isApplicable(Class extends AbstractProject> aClass) {
- // Indicates that this builder can be used with all kinds of project types
- // return FreeStyleProject.class.isAssignableFrom(aClass);
- return true;
- }
-
- /**
- * Required Method
- * @return The text to be displayed when selecting your build in the project
- */
- public String getDisplayName() {
- return "Publish build information to IBM Cloud DevOps";
- }
-
- public String getEnvironment() {
- return getEnv(Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getConsoleUrl());
- }
-
- public boolean isDebug_mode() {
- return Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).isDebug_mode();
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/PublishDeploy.java b/src/main/java/com/ibm/devops/dra/PublishDeploy.java
deleted file mode 100644
index 7f53ec9..0000000
--- a/src/main/java/com/ibm/devops/dra/PublishDeploy.java
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import com.cloudbees.plugins.credentials.CredentialsMatchers;
-import com.cloudbees.plugins.credentials.CredentialsProvider;
-import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
-import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
-import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
-import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
-import com.google.gson.*;
-import hudson.EnvVars;
-import hudson.Extension;
-import hudson.FilePath;
-import hudson.Launcher;
-import hudson.model.*;
-import hudson.security.ACL;
-import hudson.tasks.BuildStepDescriptor;
-import hudson.tasks.BuildStepMonitor;
-import hudson.tasks.Publisher;
-import hudson.util.FormValidation;
-import hudson.util.ListBoxModel;
-import jenkins.model.Jenkins;
-import jenkins.tasks.SimpleBuildStep;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.kohsuke.stapler.*;
-
-import javax.annotation.Nonnull;
-import javax.servlet.ServletException;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.text.SimpleDateFormat;
-import java.util.HashMap;
-import java.util.List;
-import java.util.TimeZone;
-
-public class PublishDeploy extends AbstractDevOpsAction implements SimpleBuildStep {
-
- private static String DEPLOYMENT_API_URL = "/organizations/{org_name}/toolchainids/{toolchain_id}/buildartifacts/{build_artifact}/builds/{build_id}/deployments";
- private final static String CONTENT_TYPE_JSON = "application/json";
-
- private PrintStream printStream;
-
- // form fields from UI
- private String applicationName;
- private String toolchainName;
- private String orgName;
- private String buildJobName;
- private String environmentName;
- private String credentialsId;
- private String applicationUrl;
- private String buildNumber;
- private static String bluemixToken;
- private static String preCredentials;
-
- //fields to support jenkins pipeline
- private String result;
- private String username;
- private String password;
-
- @DataBoundConstructor
- public PublishDeploy(String applicationName,
- String toolchainName,
- String orgName,
- String buildJobName,
- String environmentName,
- String credentialsId,
- String applicationUrl,
- OptionalBuildInfo additionalBuildInfo) {
- this.applicationName = applicationName;
- this.toolchainName = toolchainName;
- this.orgName = orgName;
- this.buildJobName = buildJobName;
- this.environmentName = environmentName;
- this.credentialsId = credentialsId;
- this.applicationUrl = applicationUrl;
-
- if (additionalBuildInfo == null) {
- this.buildNumber = null;
- } else {
- this.buildNumber = additionalBuildInfo.buildNumber;
- }
- }
-
- public PublishDeploy(HashMap envVarsMap, HashMap paramsMap) {
- this.environmentName = paramsMap.get("environment");
- this.result = paramsMap.get("result");
- this.applicationName = envVarsMap.get(APP_NAME);
- this.orgName = envVarsMap.get(ORG_NAME);
- this.toolchainName = envVarsMap.get(TOOLCHAIN_ID);
- this.username = envVarsMap.get(USERNAME);
- this.password = envVarsMap.get(PASSWORD);
- }
-
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- /**
- * We'll use this from the config.jelly.
- */
- public String getApplicationName() {
- return applicationName;
- }
-
- public String getToolchainName() {
- return toolchainName;
- }
-
- public String getOrgName() {
- return orgName;
- }
-
- public String getBuildJobName() {
- return buildJobName;
- }
-
- public String getEnvironmentName() {
- return environmentName;
- }
-
- public String getCredentialsId() {
- return credentialsId;
- }
-
- public String getApplicationUrl() {
- return applicationUrl;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public String getResult() {
- return result;
- }
-
- public static class OptionalBuildInfo {
- private String buildNumber;
-
- @DataBoundConstructor
- public OptionalBuildInfo(String buildNumber) {
- this.buildNumber = buildNumber;
- }
- }
-
- @Override
- public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher,
- @Nonnull TaskListener listener) throws InterruptedException, IOException {
-
- printStream = listener.getLogger();
- printPluginVersion(this.getClass().getClassLoader(), printStream);
-
- // Get the project name and build id from environment
- EnvVars envVars = build.getEnvironment(listener);
-
- // verify if user chooses advanced option to input customized DLMS
- String env = getDescriptor().getEnvironment();
- String targetAPI = chooseTargetAPI(env);
- String dlmsUrl = chooseDLMSUrl(env) + DEPLOYMENT_API_URL;
-
- // expand to support env vars
- this.orgName = envVars.expand(this.orgName);
- this.toolchainName = envVars.expand(this.toolchainName);
- this.applicationName = envVars.expand(this.applicationName);
- this.environmentName = envVars.expand(this.environmentName);
- this.applicationUrl = envVars.expand(this.applicationUrl);
-
- if (Util.isNullOrEmpty(orgName) || Util.isNullOrEmpty(applicationName) || Util.isNullOrEmpty(environmentName) || Util.isNullOrEmpty(toolchainName)) {
- printStream.println("[IBM Cloud DevOps] Missing few required configurations");
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Deployment Info.");
- return;
- }
-
- String buildNumber;
- // if user does not specify the build number
- if (Util.isNullOrEmpty(this.buildNumber)) {
- // locate the build job that triggers current build
- Run triggeredBuild = getTriggeredBuild(build, buildJobName, envVars, printStream);
- if (triggeredBuild == null) {
- //failed to find the build job
- return;
- } else {
- if (Util.isNullOrEmpty(this.buildJobName)) {
- // handle the case which the build job name left empty, and the pipeline case
- this.buildJobName = envVars.get("JOB_NAME");
- }
- buildNumber = getBuildNumber(buildJobName, triggeredBuild);
- }
- } else {
- buildNumber = envVars.expand(this.buildNumber);
- }
-
- dlmsUrl = dlmsUrl.replace("{org_name}", URLEncoder.encode(this.orgName, "UTF-8").replaceAll("\\+", "%20"));
- dlmsUrl = dlmsUrl.replace("{toolchain_id}", URLEncoder.encode(toolchainName, "UTF-8").replaceAll("\\+", "%20"));
- dlmsUrl = dlmsUrl.replace("{build_artifact}", URLEncoder.encode(applicationName, "UTF-8").replaceAll("\\+", "%20"));
- dlmsUrl = dlmsUrl.replace("{build_id}", URLEncoder.encode(buildNumber, "UTF-8").replaceAll("\\+", "%20"));
- String link = chooseControlCenterUrl(env) + "deploymentrisk?orgName=" + URLEncoder.encode(this.orgName, "UTF-8") + "&toolchainId=" + this.toolchainName;
- String jobUrl;
- if (checkRootUrl(printStream)) {
- jobUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
- } else {
- jobUrl = build.getAbsoluteUrl();
- }
-
- String bluemixToken;
- // get the Bluemix token
- try {
- if (Util.isNullOrEmpty(this.credentialsId)) {
- bluemixToken = getBluemixToken(username, password, targetAPI);
- } else {
- bluemixToken = getBluemixToken(build.getParent(), this.credentialsId, targetAPI);
- }
-
- printStream.println("[IBM Cloud DevOps] Log in successfully, get the Bluemix token");
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Username/Password is not correct, fail to authenticate with Bluemix");
- printStream.println("[IBM Cloud DevOps]" + e.toString());
- return;
- }
-
- if (uploadDeploymentInfo(bluemixToken, dlmsUrl, build, jobUrl)) {
- printStream.println("[IBM Cloud DevOps] Go to Control Center (" + link + ") to check your deployment status");
- }
- }
-
- private boolean uploadDeploymentInfo(String token, String dlmsUrl, Run build, String jobUrl) {
-
- String resStr = "";
-
- try {
- CloseableHttpClient httpClient = HttpClients.createDefault();
- HttpPost postMethod = new HttpPost(dlmsUrl);
- postMethod = addProxyInformation(postMethod);
- postMethod.setHeader("Authorization", token);
- postMethod.setHeader("Content-Type", CONTENT_TYPE_JSON);
-
- String buildStatus;
- Result result = build.getResult();
- if ((result != null && result.equals(Result.SUCCESS))
- || (this.result != null && this.result.equals(RESULT_SUCCESS))) {
- buildStatus = "pass";
- } else {
- buildStatus = "fail";
- }
-
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
- TimeZone utc = TimeZone.getTimeZone("UTC");
- dateFormat.setTimeZone(utc);
- String timestamp = dateFormat.format(System.currentTimeMillis());
-
- // build up the json body
- Gson gson = new Gson();
- DeploymentInfoModel deploymentInfo = new DeploymentInfoModel(applicationUrl, environmentName, jobUrl, buildStatus,
- timestamp);
-
- String json = gson.toJson(deploymentInfo);
- StringEntity data = new StringEntity(json);
- postMethod.setEntity(data);
- CloseableHttpResponse response = httpClient.execute(postMethod);
- resStr = EntityUtils.toString(response.getEntity());
-
-
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- printStream.println("[IBM Cloud DevOps] Deployment Info uploaded successfully");
- return true;
-
- } else {
- // if gets error status
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Deployment Info, response status "
- + response.getStatusLine());
-
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject resJson = element.getAsJsonObject();
- if (resJson != null && resJson.has("user_error")) {
- printStream.println("[IBM Cloud DevOps] Reason: " + resJson.get("user_error"));
- }
- }
- } catch (JsonSyntaxException e) {
- printStream.println("[IBM Cloud DevOps] Invalid Json response, response: " + resStr);
- } catch (IllegalStateException e) {
- // will be triggered when 403 Forbidden
- try {
- printStream.println("[IBM Cloud DevOps] Please check if you have the access to " + URLEncoder.encode(this.orgName, "UTF-8") + " org");
- } catch (UnsupportedEncodingException e1) {
- e1.printStackTrace();
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return false;
- }
-
- @Override
- public BuildStepMonitor getRequiredMonitorService() {
- return BuildStepMonitor.NONE;
- }
-
- // Overridden for better type safety.
- // If your plugin doesn't really define any property on Descriptor,
- // you don't have to do this.
- @Override
- public PublishDeployImpl getDescriptor() {
- return (PublishDeployImpl) super.getDescriptor();
- }
-
- /**
- * Descriptor for {@link PublishBuild}. Used as a singleton. The
- * class is marked as public so that it can be accessed from views.
- *
- *
- * See
- * src/main/resources/com/ibm/devops/dra/PublishBuild/*.jelly
- * for the actual HTML fragment for the configuration screen.
- */
- @Extension // This indicates to Jenkins that this is an implementation of an
- // extension point.
- public static final class PublishDeployImpl extends BuildStepDescriptor {
- /**
- * To persist global configuration information, simply store it in a
- * field and call save().
- *
- *
- * If you don't want fields to be persisted, use transient.
- */
-
- /**
- * In order to load the persisted global configuration, you have to call
- * load() in the constructor.
- */
- public PublishDeployImpl() {
- super(PublishDeploy.class);
- load();
- }
-
- /**
- * Performs on-the-fly validation of the form field 'credentialId'.
- *
- * @param value
- * This parameter receives the value that the user has typed.
- * @return Indicates the outcome of the validation. This is sent to the
- * browser.
- *
- * Note that returning {@link FormValidation#error(String)} does
- * not prevent the form from being saved. It just means that a
- * message will be displayed to the user.
- */
-
- public FormValidation doCheckOrgName(@QueryParameter String value) throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckApplicationName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckToolchainName(@QueryParameter String value)
- throws IOException, ServletException {
- if (value == null || value.equals("empty")) {
- return FormValidation.errorWithMarkup("Could not retrieve list of toolchains. Please check your username and password. If you have not created a toolchain, create one here.");
- }
- return FormValidation.ok();
- }
-
- public FormValidation doCheckEnvironmentName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doTestConnection(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- if (!credentialsId.equals(preCredentials) || Util.isNullOrEmpty(bluemixToken)) {
- preCredentials = credentialsId;
- try {
- String newToken = getBluemixToken(context, credentialsId, targetAPI);
- if (Util.isNullOrEmpty(newToken)) {
- bluemixToken = newToken;
- return FormValidation.warning("Got empty token");
- } else {
- return FormValidation.okWithMarkup("Connection successful");
- }
- } catch (Exception e) {
- return FormValidation.error("Failed to log in to Bluemix, please check your username/password");
- }
- } else {
- return FormValidation.okWithMarkup("Connection successful");
- }
- }
-
- /**
- * Autocompletion for build job name field
- *
- * @param value
- * - user input for the build job name field
- * @return
- */
- public AutoCompletionCandidates doAutoCompleteBuildJobName(@QueryParameter String value) {
- AutoCompletionCandidates auto = new AutoCompletionCandidates();
-
- // get all jenkins job
- List jobs = Jenkins.getInstance().getAllItems(Job.class);
- for (int i = 0; i < jobs.size(); i++) {
- String jobName = jobs.get(i).getName();
-
- if (jobName.toLowerCase().startsWith(value.toLowerCase())) {
- auto.add(jobName);
- }
- }
-
- return auto;
- }
-
- /**
- * This method is called to populate the credentials list on the Jenkins
- * config page.
- */
- public ListBoxModel doFillCredentialsIdItems(@AncestorInPath ItemGroup context,
- @QueryParameter("target") final String target) {
- StandardListBoxModel result = new StandardListBoxModel();
- result.includeEmptyValue();
- result.withMatching(CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class),
- CredentialsProvider.lookupCredentials(StandardUsernameCredentials.class, context, ACL.SYSTEM,
- URIRequirementBuilder.fromUri(target).build()));
- return result;
- }
-
- /**
- * This method is called to populate the toolchain list on the Jenkins config page.
- * @param context
- * @param orgName
- * @param credentialsId
- * @return
- */
- public ListBoxModel doFillToolchainNameItems(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId,
- @QueryParameter("orgName") final String orgName) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- try {
- bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- } catch (Exception e) {
- return new ListBoxModel();
- }
- if(isDebug_mode()){
- LOGGER.info("#######UPLOAD DEPLOYMENT INFO : calling getToolchainList#######");
- }
- ListBoxModel toolChainListBox = getToolchainList(bluemixToken, orgName, environment, isDebug_mode());
- return toolChainListBox;
- }
-
- /**
- * Required Method This is used to determine if this build step is
- * applicable for your chosen project type. (FreeStyle,
- * MultiConfiguration, Maven) Some plugin build steps might be made to
- * be only available to MultiConfiguration projects.
- *
- * @param aClass
- * The current project
- * @return a boolean indicating whether this build step can be chose
- * given the project type
- */
- public boolean isApplicable(Class extends AbstractProject> aClass) {
- // Indicates that this builder can be used with all kinds of project
- // types
- // return FreeStyleProject.class.isAssignableFrom(aClass);
- return true;
- }
-
- /**
- * Required Method
- *
- * @return The text to be displayed when selecting your build in the
- * project
- */
- public String getDisplayName() {
- return "Publish deployment information to IBM Cloud DevOps";
- }
-
- public String getEnvironment() {
- return getEnv(Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getConsoleUrl());
- }
-
- public boolean isDebug_mode() {
- return Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).isDebug_mode();
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/PublishSQ.java b/src/main/java/com/ibm/devops/dra/PublishSQ.java
deleted file mode 100644
index 25089c4..0000000
--- a/src/main/java/com/ibm/devops/dra/PublishSQ.java
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-
-import com.cloudbees.plugins.credentials.CredentialsMatchers;
-import com.cloudbees.plugins.credentials.CredentialsProvider;
-import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
-import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
-import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
-import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
-import com.google.gson.*;
-import hudson.*;
-import hudson.model.*;
-import hudson.security.ACL;
-import hudson.tasks.BuildStepDescriptor;
-import hudson.tasks.BuildStepMonitor;
-import hudson.tasks.Publisher;
-import hudson.util.FormValidation;
-import hudson.util.ListBoxModel;
-import jenkins.model.Jenkins;
-import jenkins.tasks.SimpleBuildStep;
-
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.entity.StringEntity;
-import org.kohsuke.stapler.*;
-
-import javax.annotation.Nonnull;
-import javax.servlet.ServletException;
-import java.io.*;
-import java.net.URLEncoder;
-import java.text.SimpleDateFormat;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TimeZone;
-
-
-import javax.xml.bind.DatatypeConverter;
-
-/**
- * Authenticate with Bluemix and then upload the result file to DRA
- */
-public class PublishSQ extends AbstractDevOpsAction implements SimpleBuildStep {
-
- private final static String API_PART = "/organizations/{org_name}/toolchainids/{toolchain_id}/buildartifacts/{build_artifact}/builds/{build_id}/results";
- private final static String CONTENT_TYPE_JSON = "application/json";
-
- // form fields from UI
- private String applicationName;
- private String buildJobName;
- private String orgName;
- private String toolchainName;
- private String environmentName;
- private String credentialsId;
- private String buildNumber;
-
- private String SQProjectKey;
- private String SQHostName;
- private String SQAuthToken;
- private String IBMusername;
- private String IBMpassword;
-
- private String envName;
- private boolean isDeploy;
-
- private PrintStream printStream;
- private String dlmsUrl;
- private static String bluemixToken;
- private static String preCredentials;
-
- @DataBoundConstructor
- public PublishSQ(String credentialsId,
- String orgName,
- String toolchainName,
- String buildJobName,
- String applicationName,
- String SQHostName,
- String SQAuthToken,
- String SQProjectKey,
- OptionalBuildInfo additionalBuildInfo) {
- this.credentialsId = credentialsId;
- this.orgName = orgName;
- this.toolchainName = toolchainName;
- this.buildJobName = buildJobName;
- this.applicationName = applicationName;
- this.SQHostName = SQHostName;
- this.SQAuthToken = SQAuthToken;
- this.SQProjectKey = SQProjectKey;
-
- if (additionalBuildInfo == null) {
- this.buildNumber = null;
- } else {
- this.buildNumber = additionalBuildInfo.buildNumber;
- }
- }
-
-
- public PublishSQ(HashMap envVarsMap, HashMap paramsMap) {
- this.SQProjectKey = paramsMap.get("SQProjectKey");
- this.SQHostName = paramsMap.get("SQHostName");
- this.SQAuthToken = paramsMap.get("SQAuthToken");
-
- this.applicationName = envVarsMap.get(APP_NAME);
- this.orgName = envVarsMap.get(ORG_NAME);
- this.toolchainName = envVarsMap.get(TOOLCHAIN_ID);
- this.IBMusername = envVarsMap.get(USERNAME);
- this.IBMpassword = envVarsMap.get(PASSWORD);
- }
-
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- /**
- * We'll use this from the config.jelly.
- */
- public String getApplicationName() {
- return applicationName;
- }
-
- public String getToolchainName() {
- return toolchainName;
- }
-
- public String getOrgName() {
- return orgName;
- }
-
- public String getCredentialsId() {
- return credentialsId;
- }
-
- public String getBuildJobName() {
- return buildJobName;
- }
-
- public String getSQHostName() {
- return this.SQHostName;
- }
-
- public String getSQAuthToken() {
- return this.SQAuthToken;
- }
-
- public String getSQProjectKey() {
- return this.SQProjectKey;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public boolean isDeploy() {
- return isDeploy;
- }
-
- public static class OptionalBuildInfo {
- private String buildNumber;
-
- @DataBoundConstructor
- public OptionalBuildInfo(String buildNumber) {
- this.buildNumber = buildNumber;
- }
- }
-
-
- @Override
- public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException {
-
- printStream = listener.getLogger();
- printPluginVersion(this.getClass().getClassLoader(), printStream);
-
- // Get the project name and build id from environment
- EnvVars envVars = build.getEnvironment(listener);
-
- // verify if user chooses advanced option to input customized DLMS
- String env = getDescriptor().getEnvironment();
- String targetAPI = chooseTargetAPI(env);
- String url = chooseDLMSUrl(env) + API_PART;
- // expand to support env vars
- this.orgName = envVars.expand(this.orgName);
- this.applicationName = envVars.expand(this.applicationName);
- this.toolchainName = envVars.expand(this.toolchainName);
- if (this.isDeploy || !Util.isNullOrEmpty(this.envName)) {
- this.environmentName = envVars.expand(this.envName);
- }
-
- String buildNumber;
- // if user does not specify the build number
- if (Util.isNullOrEmpty(this.buildNumber)) {
- // locate the build job that triggers current build
- Run triggeredBuild = getTriggeredBuild(build, buildJobName, envVars, printStream);
- if (triggeredBuild == null) {
- //failed to find the build job
- return;
- } else {
- if (Util.isNullOrEmpty(this.buildJobName)) {
- // handle the case which the build job name left empty, and the pipeline case
- this.buildJobName = envVars.get("JOB_NAME");
- }
- buildNumber = getBuildNumber(buildJobName, triggeredBuild);
- }
- } else {
- buildNumber = envVars.expand(this.buildNumber);
- }
-
- url = url.replace("{org_name}", URLEncoder.encode(this.orgName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{toolchain_id}", URLEncoder.encode(this.toolchainName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{build_artifact}", URLEncoder.encode(this.applicationName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{build_id}", URLEncoder.encode(buildNumber, "UTF-8").replaceAll("\\+", "%20"));
- this.dlmsUrl = url;
-
- String bluemixToken;
- // get the Bluemix token
- try {
- if (Util.isNullOrEmpty(this.credentialsId)) {
- bluemixToken = getBluemixToken(IBMusername, IBMpassword, targetAPI);
- } else {
- bluemixToken = getBluemixToken(build.getParent(), this.credentialsId, targetAPI);
- }
- printStream.println("[IBM Cloud DevOps] Log in successfully, got the Bluemix token");
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Username/Password is not correct, fail to authenticate with Bluemix");
- printStream.println("[IBM Cloud DevOps]" + e.toString());
- return;
- }
-
- Map headers = new HashMap();
- // ':' needs to be added so the SQ api knows an auth token is being used
- String SQAuthToken = DatatypeConverter.printBase64Binary((this.SQAuthToken + ":").getBytes("UTF-8"));
- headers.put("Authorization", "Basic " + SQAuthToken);
- try {
- JsonObject SQqualityGate = sendGETRequest(this.SQHostName + "/api/qualitygates/project_status?projectKey=" + this.SQProjectKey, headers);
- printStream.println("[IBM Cloud DevOps] Successfully queried SonarQube for quality gate information");
- JsonObject SQissues = getFullResponse(this.SQHostName + "/api/issues/search?statuses=OPEN&projectKeys=" + this.SQProjectKey, headers);
- printStream.println("[IBM Cloud DevOps] Successfully queried SonarQube for issue information");
- JsonObject SQratings = sendGETRequest(this.SQHostName + "/api/measures/component?metricKeys=reliability_rating,security_rating,sqale_rating&componentKey=" + this.SQProjectKey, headers);
- printStream.println("[IBM Cloud DevOps] Successfully queried SonarQube for metric information");
-
- JsonObject payload = createDLMSPayload(SQqualityGate, SQissues, SQratings);
- JsonArray urls = createPayloadUrls(this.SQHostName, this.SQProjectKey);
- sendPayloadToDLMS(bluemixToken, payload, urls);
-
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Error: Unable to upload results. Please make sure all parameters are valid");
- e.printStackTrace();
- }
- }
-
- /**
- * Constructs the urls that should be sent with the DLMS message
- *
- * @param SQHostname hostname of the SQ instance
- * @param SQKey project key of the SQ instance
- * @return an array of URLs that should be sent to dlms along with the payload
- */
- public JsonArray createPayloadUrls(String SQHostname, String SQKey) {
-
- JsonArray urls = new JsonArray();
- String url = SQHostname + "/dashboard/index/" + SQKey;
- urls.add(url);
- return urls;
- }
-
- /**
- * Combines all SQ information into one gson that can be sent to DLMS
- *
- * @param qualityGateData information pertaining to SQ gate status
- * @param issuesData information pertaining to SQ issues raised
- * @param ratingsData information pertaining to SQ ratings
- * @return combined gson object
- */
- public JsonObject createDLMSPayload(JsonObject qualityGateData, JsonObject issuesData, JsonObject ratingsData) {
-
- JsonObject payload = new JsonObject();
-
- payload.add("qualityGate", qualityGateData.get("projectStatus"));
- payload.add("issues", issuesData.get("issues"));
-
- JsonParser parser = new JsonParser();
- JsonObject component = (JsonObject)parser.parse(ratingsData.get("component").toString());
- payload.add("ratings", component.get("measures"));
-
- return payload;
- }
-
- /**
- * Sends a GET request to the provided url
- *
- * @param url the endpoint of the request
- * @param headers a map of headers where key is the header name and the map value is the header value
- * @return a JSON parsed representation of the payload returneds
- * @throws Exception
- */
- private JsonObject sendGETRequest(String url, Map headers) throws Exception {
-
- String resStr;
- CloseableHttpClient httpClient = HttpClients.createDefault();
-
- HttpGet getMethod = new HttpGet(url);
- getMethod = addProxyInformation(getMethod);
-
- //add request headers
- for(Map.Entry entry: headers.entrySet()) {
- getMethod.setHeader(entry.getKey(), entry.getValue());
- }
-
- CloseableHttpResponse response = httpClient.execute(getMethod);
- resStr = EntityUtils.toString(response.getEntity());
-
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject resJson = element.getAsJsonObject();
-
- return resJson;
- }
-
- /**
- * Get all the pages of response, a call to the api returns a single page response, this function will iterate thru all the
- * pages to get a full response. Gets 250 records per page at a time.
- *
- * @param url the endpoint of the request
- * @param headers a map of headers where key is the header name and the map value is the header value
- * @return a JSON parsed representation of the payload returned
- * @throws Exception
- */
- private JsonObject getFullResponse(String url, Map headers) throws Exception {
- JsonArray finalArray = new JsonArray();
- int recordCount = 0;
- int page = 1;
-
- do {
- String uurl = url + "&ps=250&p=" + page;
- JsonObject partResponse = sendGETRequest(uurl, headers);
- JsonArray issues = partResponse.getAsJsonArray("issues");
- finalArray.addAll(issues);
- recordCount = issues.size();
- page += 1;
- } while(recordCount > 0);
-
- JsonObject payload = new JsonObject();
- payload.add("issues", finalArray);
- return payload;
- }
-
- /**
- * Sends POST method to DLMS to upload SQ results
- *F
- * @param bluemixToken the bluemix auth header that allows us to talk to dlms
- * @param payload the content part of the payload to send to dlms
- * @param urls a json array that holds the urls for a payload
- * @return boolean based on if the request was successful or not
- */
- private boolean sendPayloadToDLMS(String bluemixToken, JsonObject payload, JsonArray urls) {
- String resStr = "";
- printStream.println("[IBM Cloud DevOps] Uploading SonarQube results...");
- try {
- CloseableHttpClient httpClient = HttpClients.createDefault();
-
- HttpPost postMethod = new HttpPost(this.dlmsUrl);
- postMethod = addProxyInformation(postMethod);
- postMethod.setHeader("Authorization", bluemixToken);
- postMethod.setHeader("Content-Type", CONTENT_TYPE_JSON);
-
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
- TimeZone utc = TimeZone.getTimeZone("UTC");
- dateFormat.setTimeZone(utc);
- String timestamp = dateFormat.format(System.currentTimeMillis());
-
- JsonObject body = new JsonObject();
-
- body.addProperty("contents", DatatypeConverter.printBase64Binary(payload.toString().getBytes("UTF-8")));
- body.addProperty("contents_type", CONTENT_TYPE_JSON);
- body.addProperty("timestamp", timestamp);
- body.addProperty("tool_name", "sonarqube");
- body.addProperty("lifecycle_stage", "sonarqube");
- body.add("url", urls);
-
- StringEntity data = new StringEntity(body.toString());
- postMethod.setEntity(data);
- CloseableHttpResponse response = httpClient.execute(postMethod);
- resStr = EntityUtils.toString(response.getEntity());
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- printStream.println("[IBM Cloud DevOps] Upload Build Information successfully");
- return true;
-
- } else {
- // if gets error status
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload, response status " + response.getStatusLine());
-
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject resJson = element.getAsJsonObject();
- if (resJson != null && resJson.has("user_error")) {
- printStream.println("[IBM Cloud DevOps] Reason: " + resJson.get("user_error"));
- }
- }
- } catch (JsonSyntaxException e) {
- printStream.println("[IBM Cloud DevOps] Invalid Json response, response: " + resStr);
- } catch (IllegalStateException e) {
- // will be triggered when 403 Forbidden
- try {
- printStream.println("[IBM Cloud DevOps] Please check if you have the access to " + URLEncoder.encode(this.orgName, "UTF-8") + " org");
- } catch (UnsupportedEncodingException e1) {
- e1.printStackTrace();
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return false;
- }
-
- @Override
- public BuildStepMonitor getRequiredMonitorService() {
- return BuildStepMonitor.NONE;
- }
-
- // Overridden for better type safety.
- // If your plugin doesn't really define any property on Descriptor,
- // you don't have to do this.
- @Override
- public PublishSQImpl getDescriptor() {
- return (PublishSQImpl)super.getDescriptor();
- }
-
- /**
- * Descriptor for {@link PublishSQ}. Used as a singleton.
- * The class is marked as public so that it can be accessed from views.
- *
- *
- * See src/main/resources/com/ibm/devops/dra/PublishTest/*.jelly
- * for the actual HTML fragment for the configuration screen.
- */
- @Extension // This indicates to Jenkins that this is an implementation of an extension point.
- public static final class PublishSQImpl extends BuildStepDescriptor {
- /**
- * To persist global configuration information,
- * simply store it in a field and call save().
- *
- *
- * If you don't want fields to be persisted, use transient.
- */
-
- /**
- * In order to load the persisted global configuration, you have to
- * call load() in the constructor.
- */
- public PublishSQImpl() {
- super(PublishSQ.class);
- load();
- }
-
- /**
- * Performs on-the-fly validation of the form field 'credentialId'.
- *
- * @param value
- * This parameter receives the value that the user has typed.
- * @return
- * Indicates the outcome of the validation. This is sent to the browser.
- *
- * Note that returning {@link FormValidation#error(String)} does not
- * prevent the form from being saved. It just means that a message
- * will be displayed to the user.
- */
-
- public FormValidation doCheckOrgName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckToolchainName(@QueryParameter String value)
- throws IOException, ServletException {
- if (value == null || value.equals("empty")) {
- return FormValidation.errorWithMarkup("Could not retrieve list of toolchains. Please check your username and password. If you have not created a toolchain, create one here.");
- }
- return FormValidation.ok();
- }
-
- public FormValidation doCheckApplicationName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckSQHostName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckSQAuthToken(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckSQProjectKey(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doTestConnection(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- if (!credentialsId.equals(preCredentials) || Util.isNullOrEmpty(bluemixToken)) {
- preCredentials = credentialsId;
- try {
- String newToken = getBluemixToken(context, credentialsId, targetAPI);
- if (Util.isNullOrEmpty(newToken)) {
- bluemixToken = newToken;
- return FormValidation.warning("Got empty token");
- } else {
- return FormValidation.okWithMarkup("Connection successful");
- }
- } catch (Exception e) {
- return FormValidation.error("Failed to log in to Bluemix, please check your username/password");
- }
- } else {
- return FormValidation.okWithMarkup("Connection successful");
- }
- }
-
- /**
- * This method is called to populate the credentials list on the Jenkins config page.
- */
- public ListBoxModel doFillCredentialsIdItems(@AncestorInPath ItemGroup context,
- @QueryParameter("target") final String target) {
- StandardListBoxModel result = new StandardListBoxModel();
- result.includeEmptyValue();
- result.withMatching(CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class),
- CredentialsProvider.lookupCredentials(
- StandardUsernameCredentials.class,
- context,
- ACL.SYSTEM,
- URIRequirementBuilder.fromUri(target).build()
- )
- );
- return result;
- }
-
- /**
- * This method is called to populate the toolchain list on the Jenkins config page.
- * @param context
- * @param orgName
- * @param credentialsId
- * @return
- */
- public ListBoxModel doFillToolchainNameItems(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId,
- @QueryParameter("orgName") final String orgName) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- try {
- bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- } catch (Exception e) {
- return new ListBoxModel();
- }
- if(isDebug_mode()){
- LOGGER.info("#######UPLOAD BUILD INFO : calling getToolchainList#######");
- }
- ListBoxModel toolChainListBox = getToolchainList(bluemixToken, orgName, environment, isDebug_mode());
- return toolChainListBox;
-
- }
-
- /**
- * Required Method
- * This is used to determine if this build step is applicable for your chosen project type. (FreeStyle, MultiConfiguration, Maven)
- * Some plugin build steps might be made to be only available to MultiConfiguration projects.
- *
- * @param aClass The current project
- * @return a boolean indicating whether this build step can be chose given the project type
- */
- public boolean isApplicable(Class extends AbstractProject> aClass) {
- // Indicates that this builder can be used with all kinds of project types
- // return FreeStyleProject.class.isAssignableFrom(aClass);
- return true;
- }
-
- /**
- * Required Method
- * @return The text to be displayed when selecting your build in the project
- */
- public String getDisplayName() {
- return "Publish SonarQube test result to IBM Cloud DevOps";
- }
-
- public String getEnvironment() {
- return getEnv(Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getConsoleUrl());
- }
-
- public boolean isDebug_mode() {
- return Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).isDebug_mode();
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/PublishTest.java b/src/main/java/com/ibm/devops/dra/PublishTest.java
deleted file mode 100644
index 65620cc..0000000
--- a/src/main/java/com/ibm/devops/dra/PublishTest.java
+++ /dev/null
@@ -1,961 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-import com.cloudbees.plugins.credentials.CredentialsMatchers;
-import com.cloudbees.plugins.credentials.CredentialsProvider;
-import com.cloudbees.plugins.credentials.common.StandardListBoxModel;
-import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
-import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
-import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
-import com.google.gson.*;
-import hudson.*;
-import hudson.model.*;
-import hudson.security.ACL;
-import hudson.tasks.BuildStepDescriptor;
-import hudson.tasks.BuildStepMonitor;
-import hudson.tasks.Publisher;
-import hudson.util.FormValidation;
-import hudson.util.ListBoxModel;
-import jenkins.model.Jenkins;
-import jenkins.tasks.SimpleBuildStep;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.mime.HttpMultipartMode;
-import org.apache.http.entity.mime.MultipartEntityBuilder;
-import org.apache.http.entity.mime.content.FileBody;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.kohsuke.stapler.*;
-
-import javax.annotation.Nonnull;
-import javax.servlet.ServletException;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.net.URLEncoder;
-import java.text.SimpleDateFormat;
-import java.util.HashMap;
-import java.util.List;
-import java.util.TimeZone;
-import java.util.HashSet;
-
-/**
- * Authenticate with Bluemix and then upload the result file to DRA
- */
-public class PublishTest extends AbstractDevOpsAction implements SimpleBuildStep {
-
- private final static String API_PART = "/organizations/{org_name}/toolchainids/{toolchain_id}/buildartifacts/{build_artifact}/builds/{build_id}/results_multipart";
- private final static String CONTENT_TYPE_JSON = "application/json";
- private final static String CONTENT_TYPE_XML = "application/xml";
-
- // form fields from UI
- private final String lifecycleStage;
- private String contents;
- private String additionalLifecycleStage;
- private String additionalContents;
- private String buildNumber;
- private String applicationName;
- private String buildJobName;
- private String orgName;
- private String toolchainName;
- private String environmentName;
- private String credentialsId;
- private String policyName;
- private boolean willDisrupt;
-
- private EnvironmentScope testEnv;
- private String envName;
- private boolean isDeploy;
-
- private PrintStream printStream;
- private File root;
- private String dlmsUrl;
- private String draUrl;
- private static String bluemixToken;
- private static String preCredentials;
-
- //fields to support jenkins pipeline
- private String username;
- private String password;
-
- @DataBoundConstructor
- public PublishTest(String lifecycleStage,
- String contents,
- String applicationName,
- String orgName,
- String toolchainName,
- String buildJobName,
- String credentialsId,
- OptionalUploadBlock additionalUpload,
- OptionalBuildInfo additionalBuildInfo,
- OptionalGate additionalGate,
- EnvironmentScope testEnv) {
- this.lifecycleStage = lifecycleStage;
- this.contents = contents;
- this.credentialsId = credentialsId;
- this.applicationName = applicationName;
- this.orgName = orgName;
- this.toolchainName = toolchainName;
- this.buildJobName = buildJobName;
- this.testEnv = testEnv;
- this.envName = testEnv.getEnvName();
- this.isDeploy = testEnv.isDeploy();
-
- if (additionalUpload == null) {
- this.additionalContents = null;
- this.additionalLifecycleStage = null;
- } else {
- this.additionalLifecycleStage = additionalUpload.additionalLifecycleStage;
- this.additionalContents = additionalUpload.additionalContents;
- }
-
- if (additionalBuildInfo == null) {
- this.buildNumber = null;
- } else {
- this.buildNumber = additionalBuildInfo.buildNumber;
- }
-
- if (additionalGate == null) {
- this.policyName = null;
- this.willDisrupt = false;
- } else {
- this.policyName = additionalGate.getPolicyName();
- this.willDisrupt = additionalGate.isWillDisrupt();
- }
- }
-
- public PublishTest(HashMap envVarsMap, HashMap paramsMap) {
- this.lifecycleStage = paramsMap.get("type");
- this.contents = paramsMap.get("fileLocation");
-
- this.applicationName = envVarsMap.get(APP_NAME);
- this.orgName = envVarsMap.get(ORG_NAME);
- this.toolchainName = envVarsMap.get(TOOLCHAIN_ID);
- this.username = envVarsMap.get(USERNAME);
- this.password = envVarsMap.get(PASSWORD);
- }
-
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- /**
- * We'll use this from the config.jelly.
- */
- public String getApplicationName() {
- return applicationName;
- }
-
- public String getToolchainName() {
- return toolchainName;
- }
-
- public String getOrgName() {
- return orgName;
- }
-
- public String getEnvironmentName() {
- return environmentName;
- }
-
- public String getBuildJobName() {
- return buildJobName;
- }
-
- public String getCredentialsId() {
- return credentialsId;
- }
-
- public String getLifecycleStage() {
- return lifecycleStage;
- }
-
- public String getContents() {
- return contents;
- }
-
- public String getAdditionalLifecycleStage() {
- return additionalLifecycleStage;
- }
-
- public String getAdditionalContents() {
- return additionalContents;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public String getPolicyName() {
- return policyName;
- }
-
- public boolean isWillDisrupt() {
- return willDisrupt;
- }
-
- public EnvironmentScope getTestEnv() {
- return testEnv;
- }
-
- public String getEnvName() {
- return envName;
- }
-
- public void setEnvName(String envName) {
- this.envName = envName;
- }
-
- public boolean isDeploy() {
- return isDeploy;
- }
-
- /**
- * Sub class for Optional Upload Block
- */
- public static class OptionalUploadBlock {
- private String additionalLifecycleStage;
- private String additionalContents;
-
- @DataBoundConstructor
- public OptionalUploadBlock(String additionalLifecycleStage, String additionalContents) {
- this.additionalLifecycleStage = additionalLifecycleStage;
- this.additionalContents = additionalContents;
- }
- }
-
- public static class OptionalBuildInfo {
- private String buildNumber;
-
- @DataBoundConstructor
- public OptionalBuildInfo(String buildNumber) {
- this.buildNumber = buildNumber;
- }
- }
-
- public static class OptionalGate {
- private String policyName;
- private boolean willDisrupt;
-
- @DataBoundConstructor
- public OptionalGate(String policyName, boolean willDisrupt) {
- this.policyName = policyName;
- setWillDisrupt(willDisrupt);
- }
-
- public String getPolicyName() {
- return policyName;
- }
-
- public boolean isWillDisrupt() {
- return willDisrupt;
- }
-
- @DataBoundSetter
- public void setWillDisrupt(boolean willDisrupt) {
- this.willDisrupt = willDisrupt;
- }
- }
-
-
- @Override
- public void perform(@Nonnull Run build, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException {
-
- printStream = listener.getLogger();
- printPluginVersion(this.getClass().getClassLoader(), printStream);
-
- // create root dir for storing test result
- root = new File(build.getRootDir(), "DRA_TestResults");
-
- // Get the project name and build id from environment
- EnvVars envVars = build.getEnvironment(listener);
-
- // verify if user chooses advanced option to input customized DLMS
- String env = getDescriptor().getEnvironment();
- String targetAPI = chooseTargetAPI(env);
- String url = chooseDLMSUrl(env) + API_PART;
- // expand to support env vars
- this.orgName = envVars.expand(this.orgName);
- this.applicationName = envVars.expand(this.applicationName);
- this.toolchainName = envVars.expand(this.toolchainName);
- this.contents = envVars.expand(this.contents);
- if (this.isDeploy || !Util.isNullOrEmpty(this.envName)) {
- this.environmentName = envVars.expand(this.envName);
- }
-
- String buildNumber;
- // if user does not specify the build number
- if (Util.isNullOrEmpty(this.buildNumber)) {
- // locate the build job that triggers current build
- Run triggeredBuild = getTriggeredBuild(build, buildJobName, envVars, printStream);
- if (triggeredBuild == null) {
- //failed to find the build job
- return;
- } else {
- if (Util.isNullOrEmpty(this.buildJobName)) {
- // handle the case which the build job name left empty, and the pipeline case
- this.buildJobName = envVars.get("JOB_NAME");
- }
- buildNumber = getBuildNumber(buildJobName, triggeredBuild);
- }
- } else {
- buildNumber = envVars.expand(this.buildNumber);
- }
-
- url = url.replace("{org_name}", URLEncoder.encode(this.orgName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{toolchain_id}", URLEncoder.encode(this.toolchainName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{build_artifact}", URLEncoder.encode(this.applicationName, "UTF-8").replaceAll("\\+", "%20"));
- url = url.replace("{build_id}", URLEncoder.encode(buildNumber, "UTF-8").replaceAll("\\+", "%20"));
- this.dlmsUrl = url;
-
- String link = chooseControlCenterUrl(env) + "deploymentrisk?orgName=" + URLEncoder.encode(this.orgName, "UTF-8") + "&toolchainId=" + this.toolchainName;
-
- String bluemixToken;
- // get the Bluemix token
- try {
- if (Util.isNullOrEmpty(this.credentialsId)) {
- bluemixToken = getBluemixToken(username, password, targetAPI);
- } else {
- bluemixToken = getBluemixToken(build.getParent(), this.credentialsId, targetAPI);
- }
-
- printStream.println("[IBM Cloud DevOps] Log in successfully, get the Bluemix token");
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Username/Password is not correct, fail to authenticate with Bluemix");
- printStream.println("[IBM Cloud DevOps]" + e.toString());
- return;
- }
-
- // parse the wildcard result files
- try {
- if(!scanAndUpload(build, workspace, contents, lifecycleStage, bluemixToken)){
- // if there is any error when scanning and uploading
- return;
- }
-
- // check to see if we need to upload additional result file
- if (!Util.isNullOrEmpty(additionalContents) && !Util.isNullOrEmpty(additionalLifecycleStage)) {
- if(!scanAndUpload(build, workspace, additionalContents, additionalLifecycleStage, bluemixToken)) {
- return;
- }
- }
- } catch (Exception e) {
- printStream.print("[IBM Cloud DevOps] Got Exception: " + e.getMessage());
- e.printStackTrace();
- return;
- }
-
- printStream.println("[IBM Cloud DevOps] Go to Control Center (" + link + ") to check your build status");
-
- // Gate
- // verify if user chooses advanced option to input customized DRA
- if (Util.isNullOrEmpty(policyName)) {
- return;
- }
-
- this.draUrl = chooseDRAUrl(env);
-
- // get decision response from DRA
- try {
- JsonObject decisionJson = getDecisionFromDRA(bluemixToken, buildNumber);
- if (decisionJson == null) {
- printStream.println("[IBM Cloud DevOps] get empty decision");
- return;
- }
-
- // retrieve the decision id to compose the report link
- String decisionId = String.valueOf(decisionJson.get("decision_id"));
- // remove the double quotes
- decisionId = decisionId.replace("\"","");
-
- // Show Proceed or Failed based on the decision
- String decision = String.valueOf(decisionJson.get("contents").getAsJsonObject().get("proceed"));
- if (decision.equals("true")) {
- decision = "Succeed";
- } else {
- decision = "Failed";
- }
-
- String cclink = chooseControlCenterUrl(env) + "deploymentrisk?orgName=" + URLEncoder.encode(this.orgName, "UTF-8") + "&toolchainId=" + this.toolchainName;
-
- String reportUrl = chooseControlCenterUrl(env) + "decisionreport?orgName=" + URLEncoder.encode(this.orgName, "UTF-8") + "&toolchainId="
- + URLEncoder.encode(toolchainName, "UTF-8") + "&reportId=" + decisionId;
- GatePublisherAction action = new GatePublisherAction(reportUrl, cclink, decision, this.policyName, build);
- build.addAction(action);
-
- printStream.println("************************************");
- printStream.println("Check IBM Cloud DevOps Gate Evaluation report here -" + reportUrl);
- printStream.println("Check IBM Cloud DevOps Deployment Risk Dashboard here -" + cclink);
- // console output for a "fail" decision
- if (decision.equals("Failed")) {
- printStream.println("IBM Cloud DevOps decision to proceed is: false");
- printStream.println("************************************");
- if (willDisrupt) {
- Result result = Result.FAILURE;
- build.setResult(result);
- }
- return;
- }
-
- // console output for a "proceed" decision
- printStream.println("IBM Cloud DevOps decision to proceed is: true");
- printStream.println("************************************");
- return;
-
- } catch (IOException e) {
- printStream.print("[IBM Cloud DevOps] Error: " + e.getMessage());
- }
-
- }
-
- @Override
- public BuildStepMonitor getRequiredMonitorService() {
- return BuildStepMonitor.NONE;
- }
-
- /**
- * Support wildcard for the result file path, scan the path and upload each matching result file to the DLMS
- * @param build - the current build
- * @param bluemixToken - the Bluemix toekn
- * @return false if there is any error when scan and upload the file
- */
- public boolean scanAndUpload(Run build, FilePath workspace, String path, String lifecycleStage, String bluemixToken) throws Exception {
- boolean errorFlag = true;
- FilePath[] filePaths = null;
-
- if (Util.isNullOrEmpty(path)) {
- // if no result file specified, create dummy result based on the build status
- filePaths = new FilePath[]{createDummyFile(build, workspace)};
- } else {
-
- // remove "./" prefix of the path if it exists
- if (path.startsWith("./")) {
- path = path.substring(2);
- }
-
- try {
- filePaths = workspace.list(path);
- } catch(InterruptedException ie) {
- printStream.println("[IBM Cloud DevOps] catching interrupt" + ie.getMessage());
- ie.printStackTrace();
- throw ie;
- } catch (IOException e) {
- printStream.println("[IBM Cloud DevOps] catching act" + e.getMessage());
- e.printStackTrace();
- throw e;
- }
- }
-
- if (filePaths == null || filePaths.length < 1) {
- printStream.println("[IBM Cloud DevOps] Error: Fail to find the file, please check the path");
- return false;
- } else {
-
- for (FilePath fp : filePaths) {
-
- // make sure the file path is for file, and copy to the master build folder
- if (!fp.isDirectory()) {
- FilePath resultFileLocation = new FilePath(new File(root, fp.getName()));
- fp.copyTo(resultFileLocation);
- }
-
- //get timestamp
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
- TimeZone utc = TimeZone.getTimeZone("UTC");
- dateFormat.setTimeZone(utc);
- String timestamp = dateFormat.format(System.currentTimeMillis());
-
- String jobUrl;
- if (checkRootUrl(printStream)) {
- jobUrl = Jenkins.getInstance().getRootUrl() + build.getUrl();
- } else {
- jobUrl = build.getAbsoluteUrl();
- }
-
- // upload the result file to DLMS
- String res = sendFormToDLMS(bluemixToken, fp, lifecycleStage, jobUrl, timestamp);
- if(!printUploadMessage(res, fp.getName())) {
- errorFlag = false;
- }
- }
- }
-
- return errorFlag;
- }
-
- /**
- * create a dummy result file following mocha format for some testing which does not generate test report
- * @param build - current build
- * @param workspace - current workspace, if it runs on slave, then it will be the path on slave
- * @return simple test result file
- */
- private FilePath createDummyFile(Run build, FilePath workspace) throws Exception {
-
- // if user did not specify the result file location, upload the dummy json file
- Gson gson = new Gson();
-
- //set the passes and failures based on the test status
- int passes, failures;
- Result result = build.getResult();
- if (result != null) {
- if (!result.equals(Result.SUCCESS)) {
- passes = 0;
- failures = 1;
- } else {
- passes = 1;
- failures = 0;
- }
- } else {
- throw new Exception("Failed to get build result");
- }
-
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
- TimeZone utc = TimeZone.getTimeZone("UTC");
- dateFormat.setTimeZone(utc);
- String start = dateFormat.format(build.getStartTimeInMillis());
- long duration = build.getDuration();
- String end = dateFormat.format(build.getStartTimeInMillis() + duration);
-
- TestResultModel.Stats stats = new TestResultModel.Stats(1, 1, passes, 0, failures, start, end, duration);
- TestResultModel.Test test = new TestResultModel.Test("unknown test", "unknown test", duration, 0, null);
- TestResultModel.Test[] tests = {test};
- String[] emptyArray = {};
- TestResultModel testResultModel = new TestResultModel(stats, tests, emptyArray, emptyArray, emptyArray);
-
- // create new dummy file
- try {
- FilePath filePath = workspace.child("simpleTest.json");
- filePath.write(gson.toJson(testResultModel), "UTF8");
- return filePath;
- } catch (IOException e) {
- printStream.println("[IBM Cloud DevOps] Failed to create dummy file in current workspace, Exception: " + e.getMessage());
- }
-
- return null;
- }
-
- /**
- * print out the response message from DLMS to the console log
- * @param response - response from DLMS
- * @param fileName - uploaded filename
- * @return true if upload succeed, otherwise return false
- */
- private boolean printUploadMessage(String response, String fileName) {
- if (response.contains("Error")) {
- printStream.println("[IBM Cloud DevOps] " + response);
- } else if (response.contains("200")) {
- printStream.println("[IBM Cloud DevOps] Upload [" + fileName + "] SUCCESSFUL");
- return true;
- } else {
- printStream.println("[IBM Cloud DevOps]" + response + ", Upload [" + fileName + "] FAILED");
- }
-
- return false;
- }
-
- /**
- * * Send POST request to DLMS back end with the result file
- * @param bluemixToken - the Bluemix token
- * @param contents - the result file
- * @param jobUrl - the build url of the build job in Jenkins
- * @param timestamp
- * @return - response/error message from DLMS
- */
- public String sendFormToDLMS(String bluemixToken, FilePath contents, String lifecycleStage, String jobUrl, String timestamp) throws IOException {
-
- // create http client and post method
- CloseableHttpClient httpClient = HttpClients.createDefault();
- HttpPost postMethod = new HttpPost(this.dlmsUrl);
-
- postMethod = addProxyInformation(postMethod);
- // build up multi-part forms
- MultipartEntityBuilder builder = MultipartEntityBuilder.create();
- builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
- if (contents != null) {
-
- File file = new File(root, contents.getName());
- FileBody fileBody = new FileBody(file);
- builder.addPart("contents", fileBody);
-
-
- builder.addTextBody("test_artifact", file.getName());
- if (this.isDeploy) {
- builder.addTextBody("environment_name", environmentName);
- }
- //Todo check the value of lifecycleStage
- builder.addTextBody("lifecycle_stage", lifecycleStage);
- builder.addTextBody("url", jobUrl);
- builder.addTextBody("timestamp", timestamp);
-
- String fileExt = FilenameUtils.getExtension(contents.getName());
- String contentType;
- switch (fileExt) {
- case "json":
- contentType = CONTENT_TYPE_JSON;
- break;
- case "xml":
- contentType = CONTENT_TYPE_XML;
- break;
- default:
- return "Error: " + contents.getName() + " is an invalid result file type";
- }
-
- builder.addTextBody("contents_type", contentType);
- HttpEntity entity = builder.build();
- postMethod.setEntity(entity);
- postMethod.setHeader("Authorization", bluemixToken);
- } else {
- return "Error: File is null";
- }
-
-
- CloseableHttpResponse response = null;
- try {
- response = httpClient.execute(postMethod);
- // parse the response json body to display detailed info
- String resStr = EntityUtils.toString(response.getEntity());
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
-
- if (!element.isJsonObject()) {
- // 401 Forbidden
- return "Error: Upload is Forbidden, please check your org name. Error message: " + element.toString();
- } else {
- JsonObject resJson = element.getAsJsonObject();
- if (resJson != null && resJson.has("status")) {
- return String.valueOf(response.getStatusLine()) + "\n" + resJson.get("status");
- } else {
- // other cases
- return String.valueOf(response.getStatusLine());
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- throw e;
- }
- }
-
-
- /**
- * Send a request to DRA backend to get a decision
- * @param buildId - build ID, get from Jenkins environment
- * @return - the response decision Json file
- */
- private JsonObject getDecisionFromDRA(String bluemixToken, String buildId) throws IOException {
- // create http client and post method
- CloseableHttpClient httpClient = HttpClients.createDefault();
-
- String url = this.draUrl;
- url = url + "/organizations/" + orgName +
- "/toolchainids/" + toolchainName +
- "/buildartifacts/" + URLEncoder.encode(applicationName, "UTF-8").replaceAll("\\+", "%20") +
- "/builds/" + buildId +
- "/policies/" + URLEncoder.encode(policyName, "UTF-8").replaceAll("\\+", "%20") +
- "/decisions";
- if (this.isDeploy) {
- url = url.concat("?environment_name=" + environmentName);
- }
-
- HttpPost postMethod = new HttpPost(url);
-
- postMethod = addProxyInformation(postMethod);
- postMethod.setHeader("Authorization", bluemixToken);
- postMethod.setHeader("Content-Type", CONTENT_TYPE_JSON);
-
- CloseableHttpResponse response = httpClient.execute(postMethod);
- String resStr = EntityUtils.toString(response.getEntity());
-
- try {
- if (response.getStatusLine().toString().contains("200")) {
- // get 200 response
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject resJson = element.getAsJsonObject();
- printStream.println("[IBM Cloud DevOps] Get decision successfully");
- return resJson;
- } else {
- // if gets error status
- printStream.println("[IBM Cloud DevOps] Error: Failed to get a decision, response status " + response.getStatusLine());
-
- JsonParser parser = new JsonParser();
- JsonElement element = parser.parse(resStr);
- JsonObject resJson = element.getAsJsonObject();
- if (resJson != null && resJson.has("message")) {
- printStream.println("[IBM Cloud DevOps] Reason: " + resJson.get("message"));
- }
- }
- } catch (JsonSyntaxException e) {
- printStream.println("[IBM Cloud DevOps] Invalid Json response, response: " + resStr);
- }
-
- return null;
-
- }
-
- // Overridden for better type safety.
- // If your plugin doesn't really define any property on Descriptor,
- // you don't have to do this.
- @Override
- public PublishTestImpl getDescriptor() {
- return (PublishTestImpl)super.getDescriptor();
- }
-
- /**
- * Descriptor for {@link PublishTest}. Used as a singleton.
- * The class is marked as public so that it can be accessed from views.
- *
- *
- * See src/main/resources/com/ibm/devops/dra/PublishTest/*.jelly
- * for the actual HTML fragment for the configuration screen.
- */
- @Extension // This indicates to Jenkins that this is an implementation of an extension point.
- public static final class PublishTestImpl extends BuildStepDescriptor {
- /**
- * To persist global configuration information,
- * simply store it in a field and call save().
- *
- *
- * If you don't want fields to be persisted, use transient.
- */
-
- /**
- * In order to load the persisted global configuration, you have to
- * call load() in the constructor.
- */
- public PublishTestImpl() {
- super(PublishTest.class);
- load();
- }
-
- /**
- * Performs on-the-fly validation of the form field 'credentialId'.
- *
- * @param value
- * This parameter receives the value that the user has typed.
- * @return
- * Indicates the outcome of the validation. This is sent to the browser.
- *
- * Note that returning {@link FormValidation#error(String)} does not
- * prevent the form from being saved. It just means that a message
- * will be displayed to the user.
- */
-
- public FormValidation doCheckOrgName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckApplicationName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckToolchainName(@QueryParameter String value)
- throws IOException, ServletException {
- if (value == null || value.equals("empty")) {
- return FormValidation.errorWithMarkup("Could not retrieve list of toolchains. Please check your username and password. If you have not created a toolchain, create one here.");
- }
- return FormValidation.ok();
- }
-
- public FormValidation doCheckEnvironmentName(@QueryParameter String value)
- throws IOException, ServletException {
- return FormValidation.validateRequired(value);
- }
-
- public FormValidation doCheckPolicyName(@QueryParameter String value) {
-
- if (value == null || value.equals("empty")) {
- return FormValidation.errorWithMarkup("Fail to get the policies, please check your username/password or org name and make sure you have created policies for this org and toolchain.");
- }
- return FormValidation.ok();
- }
-
- public FormValidation doTestConnection(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- if (!credentialsId.equals(preCredentials) || Util.isNullOrEmpty(bluemixToken)) {
- preCredentials = credentialsId;
- try {
- String bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- if (Util.isNullOrEmpty(bluemixToken)) {
- PublishTest.bluemixToken = bluemixToken;
- return FormValidation.warning("Got empty token");
- } else {
- return FormValidation.okWithMarkup("Connection successful");
- }
- } catch (Exception e) {
- return FormValidation.error("Failed to log in to Bluemix, please check your username/password");
- }
- } else {
-
- return FormValidation.okWithMarkup("Connection successful");
- }
- }
-
- /**
- * Autocompletion for build job name field
- * @param value - user input for the build job name field
- * @return
- */
- public AutoCompletionCandidates doAutoCompleteBuildJobName(@QueryParameter String value) {
- AutoCompletionCandidates auto = new AutoCompletionCandidates();
-
- // get all jenkins job
- List jobs = Jenkins.getInstance().getAllItems(Job.class);
- HashSet jobSet = new HashSet<>();
- for (int i = 0; i < jobs.size(); i++) {
- String jobName = jobs.get(i).getName();
-
- if (jobName.toLowerCase().startsWith(value.toLowerCase())) {
- jobSet.add(jobName);
- }
- }
-
- for (String s : jobSet) {
- auto.add(s);
- }
-
- return auto;
- }
-
- /**
- * This method is called to populate the credentials list on the Jenkins config page.
- */
- public ListBoxModel doFillCredentialsIdItems(@AncestorInPath ItemGroup context,
- @QueryParameter("target") final String target) {
- StandardListBoxModel result = new StandardListBoxModel();
- result.includeEmptyValue();
- result.withMatching(CredentialsMatchers.instanceOf(StandardUsernamePasswordCredentials.class),
- CredentialsProvider.lookupCredentials(
- StandardUsernameCredentials.class,
- context,
- ACL.SYSTEM,
- URIRequirementBuilder.fromUri(target).build()
- )
- );
- return result;
- }
-
- /**
- * This method is called to populate the policy list on the Jenkins config page.
- * @param context
- * @param orgName
- * @param credentialsId
- * @return
- */
- public ListBoxModel doFillPolicyNameItems(@AncestorInPath ItemGroup context,
- @RelativePath("..") @QueryParameter final String orgName,
- @RelativePath("..") @QueryParameter final String toolchainName,
- @RelativePath("..") @QueryParameter final String credentialsId) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- try {
- // if user changes to a different credential, need to get a new token
- if (!credentialsId.equals(preCredentials) || Util.isNullOrEmpty(bluemixToken)) {
- bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- preCredentials = credentialsId;
- }
- } catch (Exception e) {
- return new ListBoxModel();
- }
- if(isDebug_mode()){
- LOGGER.info("#######UPLOAD TEST RESULTS : calling getPolicyList#######");
- }
- return getPolicyList(bluemixToken, orgName, toolchainName, environment, isDebug_mode());
- }
-
- /**
- * This method is called to populate the toolchain list on the Jenkins config page.
- * @param context
- * @param orgName
- * @param credentialsId
- * @return
- */
- public ListBoxModel doFillToolchainNameItems(@AncestorInPath ItemGroup context,
- @QueryParameter("credentialsId") final String credentialsId,
- @QueryParameter("orgName") final String orgName) {
- String environment = getEnvironment();
- String targetAPI = chooseTargetAPI(environment);
- try {
- bluemixToken = getBluemixToken(context, credentialsId, targetAPI);
- } catch (Exception e) {
- return new ListBoxModel();
- }
- if(isDebug_mode()){
- LOGGER.info("#######UPLOAD TEST RESULTS : calling getToolchainList#######");
- }
- ListBoxModel toolChainListBox = getToolchainList(bluemixToken, orgName, environment, isDebug_mode());
- return toolChainListBox;
-
- }
-
- /**
- * Required Method
- * This is used to determine if this build step is applicable for your chosen project type. (FreeStyle, MultiConfiguration, Maven)
- * Some plugin build steps might be made to be only available to MultiConfiguration projects.
- *
- * @param aClass The current project
- * @return a boolean indicating whether this build step can be chose given the project type
- */
- public boolean isApplicable(Class extends AbstractProject> aClass) {
- // Indicates that this builder can be used with all kinds of project types
- // return FreeStyleProject.class.isAssignableFrom(aClass);
- return true;
- }
-
- public ListBoxModel doFillLifecycleStageItems(@QueryParameter("lifecycleStage") final String selection) {
- return fillTestType();
- }
-
- public ListBoxModel doFillAdditionalLifecycleStageItems(@QueryParameter("additionalLifecycleStage") final String selection) {
- return fillTestType();
- }
-
- /**
- * fill the dropdown list of rule type
- * @return the dropdown list model
- */
- public ListBoxModel fillTestType() {
- ListBoxModel model = new ListBoxModel();
-
- model.add("Unit Test", "unittest");
- model.add("Functional Verification Test", "fvt");
- model.add("Code Coverage", "code");
- return model;
- }
-
- /**
- * Required Method
- * @return The text to be displayed when selecting your build in the project
- */
- public String getDisplayName() {
- return "Publish test result to IBM Cloud DevOps";
- }
-
- public String getEnvironment() {
- return getEnv(Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).getConsoleUrl());
- }
-
- public boolean isDebug_mode() {
- return Jenkins.getInstance().getDescriptorByType(DevOpsGlobalConfiguration.class).isDebug_mode();
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/TestResultModel.java b/src/main/java/com/ibm/devops/dra/TestResultModel.java
deleted file mode 100644
index 2116651..0000000
--- a/src/main/java/com/ibm/devops/dra/TestResultModel.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-/**
- * Object for creating dummy test result file following mocha format
- */
-public class TestResultModel{
-
- // sub-model for stats
- public static class Stats {
- private Integer suites;
- private Integer tests;
- private Integer passes;
- private Integer pending;
- private Integer failures;
- private String start;
- private String end;
- private Long duration;
-
- public Stats(Integer suites,
- Integer tests,
- Integer passes,
- Integer pending,
- Integer failures,
- String start,
- String end,
- Long duration) {
- this.suites = suites;
- this.tests = tests;
- this.passes = passes;
- this.pending = pending;
- this.failures = failures;
- this.start = start;
- this.end = end;
- this.duration = duration;
- }
-
- public Integer getSuites() {
- return suites;
- }
-
- public Integer getTests() {
- return tests;
- }
-
- public Integer getPasses() {
- return passes;
- }
-
- public Integer getPending() {
- return pending;
- }
-
- public Integer getFailures() {
- return failures;
- }
-
- public String getStart() {
- return start;
- }
-
- public String getEnd() {
- return end;
- }
-
- public Long getDuration() {
- return duration;
- }
- }
-
- // sub-model for test
- public static class Test {
- private String title;
- private String fullTitle;
- private Long duration;
- private Integer currentRetry;
- private Object err;
-
- public Test(String title,
- String fullTitle,
- Long duration,
- Integer currentRetry,
- Object err) {
- this.title = title;
- this.fullTitle = fullTitle;
- this.duration = duration;
- this.currentRetry = currentRetry;
- this.err = err;
- }
-
- public String getTitle() {
- return title;
- }
-
- public String getFullTitle() {
- return fullTitle;
- }
-
- public Long getDuration() {
- return duration;
- }
-
- public Integer getCurrentRetry() {
- return currentRetry;
- }
-
- public Object getErr() {
- return err;
- }
- }
-
- private Stats stats;
- private Test[] tests;
- private String[] pending;
- private String[] failures;
- private String[] passes;
-
- public TestResultModel(Stats stats,
- Test[] tests,
- String[] pending,
- String[] failures,
- String[] passes) {
- this.stats = stats;
- this.tests = tests.clone();
- this.pending = pending.clone();
- this.failures = failures.clone();
- this.passes = passes.clone();
- }
-
- public Stats getStats() {
- return stats;
- }
-
- public Test[] getTests() {
- return tests.clone();
- }
-
- public String[] getPending() {
- return pending.clone();
- }
-
- public String[] getFailures() {
- return failures.clone();
- }
-
- public String[] getPasses() {
- return passes.clone();
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/Util.java b/src/main/java/com/ibm/devops/dra/Util.java
deleted file mode 100644
index 41dac8d..0000000
--- a/src/main/java/com/ibm/devops/dra/Util.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra;
-
-
-import hudson.EnvVars;
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Utilities functions
- */
-
-public class Util {
- /**
- * check if the str is null or empty
- * @param str
- * @return true if it is null or empty
- */
- public static boolean isNullOrEmpty(String str) {
- if (str == null || str.isEmpty()) {
- return true;
- }
- return false;
- }
-
- public static boolean allNotNullOrEmpty(String... strs) {
- for (String str : strs) {
- if (isNullOrEmpty(str)) {
- return false;
- }
- }
- return true;
- }
-
- public static boolean allNotNullOrEmpty(HashMap vars, PrintStream printStream) {
- for (Map.Entry e : vars.entrySet()) {
- if (isNullOrEmpty(e.getValue())) {
- if (e.getKey().contains("IBM"))
- printStream.println("[IBM Cloud DevOps] Missing environment variables \"" + e.getKey() + "\" configurations");
- else
- printStream.println("[IBM Cloud DevOps] Missing required parameters, \"" + e.getKey() + "\"");
- return false;
- }
- }
- return true;
- }
-
- public static boolean validateEnvVariables(EnvVars envVars, PrintStream printStream) {
- Boolean valid = true;
- if(envVars != null) {
- String org = getOrg(envVars);
- String space = getSpace(envVars);
- String appName = getAppName(envVars);
- String user = getUser(envVars);
- String pwd = getPassword(envVars);
- String webhook = getWebhookUrl(envVars);
-
- // perform validation and warn for each missing required property
- if (isNullOrEmpty(org)) {
- printStream.println("[IBM Cloud DevOps] Missing required property IBM_CLOUD_DEVOPS_ORG");
- valid = false;
- }
- if (isNullOrEmpty(space)) {
- printStream.println("[IBM Cloud DevOps] Missing required property IBM_CLOUD_DEVOPS_SPACE");
- valid = false;
- }
- if (isNullOrEmpty(appName)) {
- printStream.println("[IBM Cloud DevOps] Missing required property IBM_CLOUD_DEVOPS_APP_NAME");
- valid = false;
- }
- if (isNullOrEmpty(user)) {
- printStream.println("[IBM Cloud DevOps] Missing required property IBM_CLOUD_DEVOPS_CREDS_USR");
- valid = false;
- }
- if (isNullOrEmpty(pwd)) {
- printStream.println("[IBM Cloud DevOps] Missing required property IBM_CLOUD_DEVOPS_CREDS_PSW");
- valid = false;
- }
- if (isNullOrEmpty(webhook)) {
- printStream.println("[IBM Cloud DevOps] Missing required property IBM_CLOUD_DEVOPS_WEBHOOK_URL");
- valid = false;
- }
- }
- return valid;
- }
-
- public static String getWebhookUrl(EnvVars envVars) {
- String webhook = envVars.get("IBM_CLOUD_DEVOPS_WEBHOOK_URL");
- //backward compatibility
- if (isNullOrEmpty(webhook)) {
- webhook = envVars.get("ICD_WEBHOOK_URL");
- }
- return webhook;
- }
-
- public static String getOrg(EnvVars envVars) {
- String org = envVars.get("IBM_CLOUD_DEVOPS_ORG");
- //backward compatibility
- if (isNullOrEmpty(org)) {
- org = envVars.get("CF_ORG");
- }
- return org;
- }
-
- public static String getSpace(EnvVars envVars) {
- String space = envVars.get("IBM_CLOUD_DEVOPS_SPACE");
- //backward compatibility
- if (isNullOrEmpty(space)) {
- space = envVars.get("CF_SPACE");
- }
- return space;
- }
-
- public static String getAppName(EnvVars envVars) {
- String appName = envVars.get("IBM_CLOUD_DEVOPS_APP_NAME");
- //backward compatibility
- if (isNullOrEmpty(appName)) {
- appName = envVars.get("CF_APP");
- }
- return appName;
- }
-
- public static String getUser(EnvVars envVars) {
- String user = envVars.get("IBM_CLOUD_DEVOPS_CREDS_USR");
- //backward compatibility
- if (isNullOrEmpty(user)) {
- user = envVars.get("CF_CREDS_USR");
- }
- return user;
- }
-
- public static String getPassword(EnvVars envVars) {
- String pwd = envVars.get("IBM_CLOUD_DEVOPS_CREDS_PSW");
- //backward compatibility
- if (isNullOrEmpty(pwd)) {
- pwd = envVars.get("CF_CREDS_PSW");
- }
- return pwd;
- }
-
- public static String getGitRepoUrl(EnvVars envVars) {
- String gitUrl = envVars.get("GIT_URL");
- if (isNullOrEmpty(gitUrl)) {
- gitUrl = envVars.get("GIT_REPO"); // used in pipeline scripts
- }
- return gitUrl;
- }
-
- public static String getGitBranch(EnvVars envVars) {
- return envVars.get("GIT_BRANCH");
- }
-
- public static String getGitCommit(EnvVars envVars) {
- return envVars.get("GIT_COMMIT");
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/AbstractDevOpsStep.java b/src/main/java/com/ibm/devops/dra/steps/AbstractDevOpsStep.java
deleted file mode 100644
index 76f0fb7..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/AbstractDevOpsStep.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.ibm.devops.dra.steps;
-
-import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
-import org.kohsuke.stapler.DataBoundSetter;
-
-/**
- * Created by lix on 8/8/17.
- */
-abstract public class AbstractDevOpsStep extends AbstractStepImpl {
- private String applicationName;
- private String orgName;
- private String credentialsId;
- private String toolchainId;
-
- @DataBoundSetter
- public void setApplicationName(String applicationName) {
- this.applicationName = applicationName;
- }
-
- @DataBoundSetter
- public void setOrgName(String orgName) {
- this.orgName = orgName;
- }
-
- @DataBoundSetter
- public void setCredentialsId(String credentialsId) {
- this.credentialsId = credentialsId;
- }
-
- @DataBoundSetter
- public void setToolchainId(String toolchainId) {
- this.toolchainId = toolchainId;
- }
-
- public String getApplicationName() {
- return applicationName;
- }
-
- public String getOrgName() {
- return orgName;
- }
-
- public String getCredentialsId() {
- return credentialsId;
- }
-
- public String getToolchainId() {
- return toolchainId;
- }
-
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/EvaluateGateStep.java b/src/main/java/com/ibm/devops/dra/steps/EvaluateGateStep.java
deleted file mode 100644
index f8ca38d..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/EvaluateGateStep.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import hudson.Extension;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.DataBoundSetter;
-
-import javax.annotation.Nonnull;
-
-public class EvaluateGateStep extends AbstractDevOpsStep {
-
- // required parameters to support pipeline script
- private String policy;
-
- // optional gate parameters
- private String forceDecision;
- private String environment;
- private String buildNumber;
-
- @DataBoundConstructor
- public EvaluateGateStep(String policy) {
- this.policy = policy;
- }
-
- @DataBoundSetter
- public void setEnvironment(String environment) {
- this.environment = environment;
- }
-
- @DataBoundSetter
- public void setForceDecision(String forceDecision) {
- this.forceDecision = forceDecision;
- }
-
- @DataBoundSetter
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public String getEnvironment() {
- return environment;
- }
-
- public String getPolicy() {
- return policy;
- }
-
- public String getForceDecision() {
- return forceDecision;
- }
-
- @Extension
- public static class DescriptorImpl extends AbstractStepDescriptorImpl {
-
- public DescriptorImpl() { super(EvaluateGateStepExecution.class); }
-
- @Override
- public String getFunctionName() {
- return "evaluateGate";
- }
-
- @Nonnull
- @Override
- public String getDisplayName() {
- return "IBM Cloud DevOps Gate";
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/EvaluateGateStepExecution.java b/src/main/java/com/ibm/devops/dra/steps/EvaluateGateStepExecution.java
deleted file mode 100644
index f025a8f..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/EvaluateGateStepExecution.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import com.ibm.devops.dra.EvaluateGate;
-import com.ibm.devops.dra.Util;
-import hudson.AbortException;
-import hudson.EnvVars;
-import hudson.FilePath;
-import hudson.Launcher;
-import hudson.model.Run;
-import hudson.model.TaskListener;
-import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution;
-import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
-
-import javax.inject.Inject;
-import java.io.PrintStream;
-import java.util.HashMap;
-
-import static com.ibm.devops.dra.AbstractDevOpsAction.setRequiredEnvVars;
-
-public class EvaluateGateStepExecution extends AbstractSynchronousNonBlockingStepExecution {
- private static final long serialVersionUID = 1L;
- @Inject
- private transient EvaluateGateStep step;
-
- @StepContextParameter
- private transient TaskListener listener;
- @StepContextParameter
- private transient FilePath ws;
- @StepContextParameter
- private transient Launcher launcher;
- @StepContextParameter
- private transient Run build;
- @StepContextParameter
- private transient EnvVars envVars;
-
- @Override
- protected Void run() throws Exception {
-
- PrintStream printStream = listener.getLogger();
- HashMap requiredEnvVars = setRequiredEnvVars(step, envVars);
-
-
- //check all the required env vars
- if (!Util.allNotNullOrEmpty(requiredEnvVars, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to get Gate decision.");
- return null;
- }
-
- String policy = step.getPolicy();
- if (Util.isNullOrEmpty(policy)) {
- printStream.println("[IBM Cloud DevOps] evaluateGate is missing required parameters, " +
- "please make sure you specify \"policy\"");
- printStream.println("[IBM Cloud DevOps] Error: Failed to run evaluate Gate.");
- return null;
- }
-
- Boolean willDisrupt = false;
- if (!Util.isNullOrEmpty(step.getForceDecision()) && step.getForceDecision().toLowerCase().equals("true")) {
- willDisrupt = true;
- }
-
- // optional build number, if user wants to set their own build number
- String buildNumber = step.getBuildNumber();
- EvaluateGate evaluateGate = new EvaluateGate(requiredEnvVars, policy, step.getEnvironment(), willDisrupt);
- try {
- if (!Util.isNullOrEmpty(buildNumber)) {
- evaluateGate.setBuildNumber(buildNumber);
- }
- evaluateGate.perform(build, ws, launcher, listener);
- } catch (AbortException e) {
- throw new AbortException("Decision is fail");
- }
-
- return null;
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/PublishBuildStep.java b/src/main/java/com/ibm/devops/dra/steps/PublishBuildStep.java
deleted file mode 100644
index bc3847a..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/PublishBuildStep.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import hudson.Extension;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.DataBoundSetter;
-
-import javax.annotation.Nonnull;
-
-public class PublishBuildStep extends AbstractDevOpsStep {
-
- // required parameters to support pipeline script
- private String result;
- private String gitRepo;
- private String gitBranch;
- private String gitCommit;
-
- // custom build number, optional
- private String buildNumber;
-
- @DataBoundConstructor
- public PublishBuildStep(String result, String gitRepo, String gitBranch, String gitCommit) {
- this.gitRepo = gitRepo;
- this.gitBranch = gitBranch;
- this.gitCommit = gitCommit;
- this.result = result;
- }
-
- @DataBoundSetter
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- public String getGitRepo() {
- return gitRepo;
- }
-
- public String getGitBranch() {
- return gitBranch;
- }
-
- public String getGitCommit() {
- return gitCommit;
- }
-
- public String getResult() {
- return result;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- @Extension
- public static class DescriptorImpl extends AbstractStepDescriptorImpl {
-
- public DescriptorImpl() { super(PublishBuildStepExecution.class); }
-
- @Override
- public String getFunctionName() {
- return "publishBuildRecord";
- }
-
- @Nonnull
- @Override
- public String getDisplayName() {
- return "Publish build record to IBM Cloud DevOps";
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/PublishBuildStepExecution.java b/src/main/java/com/ibm/devops/dra/steps/PublishBuildStepExecution.java
deleted file mode 100644
index 4151932..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/PublishBuildStepExecution.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import com.ibm.devops.dra.PublishBuild;
-import com.ibm.devops.dra.Util;
-import hudson.EnvVars;
-import hudson.FilePath;
-import hudson.Launcher;
-import hudson.model.Run;
-import hudson.model.TaskListener;
-import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution;
-import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
-
-import javax.inject.Inject;
-import java.io.PrintStream;
-import java.util.HashMap;
-
-import static com.ibm.devops.dra.AbstractDevOpsAction.*;
-
-public class PublishBuildStepExecution extends AbstractSynchronousNonBlockingStepExecution {
- private static final long serialVersionUID = 1L;
- @Inject
- private transient PublishBuildStep step;
-
- @StepContextParameter
- private transient TaskListener listener;
- @StepContextParameter
- private transient FilePath ws;
- @StepContextParameter
- private transient Launcher launcher;
- @StepContextParameter
- private transient Run build;
- @StepContextParameter
- private transient EnvVars envVars;
-
- @Override
- protected Void run() throws Exception {
-
- PrintStream printStream = listener.getLogger();
- HashMap requiredEnvVars = setRequiredEnvVars(step, envVars);
-
- //check all the required env vars
- if (!Util.allNotNullOrEmpty(requiredEnvVars, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Build Record.");
- return null;
- }
-
- //check all the required parameters
- HashMap requiredParams = new HashMap<>();
- String result = step.getResult();
- requiredParams.put("result", result);
- requiredParams.put("gitRepo", step.getGitRepo());
- requiredParams.put("gitBranch", step.getGitBranch());
- requiredParams.put("gitCommit", step.getGitCommit());
-
- // optional build number, if user wants to set their own build number
- String buildNumber = step.getBuildNumber();
-
- if (!Util.allNotNullOrEmpty(requiredEnvVars, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Build Record.");
- return null;
- }
-
- if (result.equals(RESULT_SUCCESS) || result.equals(RESULT_FAIL)) {
- PublishBuild publishBuild = new PublishBuild(requiredEnvVars, requiredParams);
-
- if (!Util.isNullOrEmpty(buildNumber)) {
- publishBuild.setBuildNumber(buildNumber);
- }
- publishBuild.perform(build, ws, launcher, listener);
- } else {
- printStream.println("[IBM Cloud DevOps] the \"result\" in the publishBuildRecord should be either \""
- + RESULT_SUCCESS + "\" or \"" + RESULT_FAIL + "\"");
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Build Record.");
- }
-
- return null;
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/PublishDeployStep.java b/src/main/java/com/ibm/devops/dra/steps/PublishDeployStep.java
deleted file mode 100644
index 5292ec2..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/PublishDeployStep.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import hudson.Extension;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.DataBoundSetter;
-
-import javax.annotation.Nonnull;
-
-public class PublishDeployStep extends AbstractDevOpsStep {
-
- // required parameters to support pipeline script
- private String result;
- private String environment;
- private String appUrl;
-
- // custom build number, optional
- private String buildNumber;
-
- @DataBoundConstructor
- public PublishDeployStep(String result, String environment, String appUrl) {
- this.environment = environment;
- this.appUrl = appUrl;
- this.result = result;
- }
-
- @DataBoundSetter
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public String getEnvironment() {
- return environment;
- }
-
- public String getAppUrl() {
- return appUrl;
- }
-
- public String getResult() {
- return result;
- }
-
- @Extension
- public static class DescriptorImpl extends AbstractStepDescriptorImpl {
-
- public DescriptorImpl() { super(PublishDeployStepExecution.class); }
-
- @Override
- public String getFunctionName() {
- return "publishDeployRecord";
- }
-
- @Nonnull
- @Override
- public String getDisplayName() {
- return "Publish deploy record to IBM Cloud DevOps";
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/PublishDeployStepExecution.java b/src/main/java/com/ibm/devops/dra/steps/PublishDeployStepExecution.java
deleted file mode 100644
index 8369223..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/PublishDeployStepExecution.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import com.ibm.devops.dra.PublishDeploy;
-import com.ibm.devops.dra.Util;
-import hudson.EnvVars;
-import hudson.FilePath;
-import hudson.Launcher;
-import hudson.model.Run;
-import hudson.model.TaskListener;
-import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution;
-import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
-
-import javax.inject.Inject;
-import java.io.PrintStream;
-import java.util.HashMap;
-
-import static com.ibm.devops.dra.AbstractDevOpsAction.RESULT_FAIL;
-import static com.ibm.devops.dra.AbstractDevOpsAction.RESULT_SUCCESS;
-import static com.ibm.devops.dra.AbstractDevOpsAction.setRequiredEnvVars;
-
-public class PublishDeployStepExecution extends AbstractSynchronousNonBlockingStepExecution {
- private static final long serialVersionUID = 1L;
- @Inject
- private transient PublishDeployStep step;
-
- @StepContextParameter
- private transient TaskListener listener;
- @StepContextParameter
- private transient FilePath ws;
- @StepContextParameter
- private transient Launcher launcher;
- @StepContextParameter
- private transient Run build;
- @StepContextParameter
- private transient EnvVars envVars;
-
-
- @Override
- protected Void run() throws Exception {
-
- PrintStream printStream = listener.getLogger();
- HashMap requiredEnvVars = setRequiredEnvVars(step, envVars);
-
- //check all the required env vars
- if (!Util.allNotNullOrEmpty(requiredEnvVars, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Test Result.");
- return null;
- }
-
- //check all the required parameters
- HashMap requiredParams = new HashMap<>();
- String result = step.getResult();
- requiredParams.put("environment", step.getEnvironment());
- requiredParams.put("result", result);
-
- // optional build number, if user wants to set their own build number
- String buildNumber = step.getBuildNumber();
- if (!Util.allNotNullOrEmpty(requiredParams, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Deploy Record.");
- return null;
- }
-
- if (result.equals(RESULT_SUCCESS) || result.equals(RESULT_FAIL)) {
- PublishDeploy publishDeploy = new PublishDeploy(requiredEnvVars, requiredParams);
- if (!Util.isNullOrEmpty(buildNumber)) {
- publishDeploy.setBuildNumber(buildNumber);
- }
- publishDeploy.perform(build, ws, launcher, listener);
- } else {
- printStream.println("[IBM Cloud DevOps] the \"result\" in the publishDeployRecord should be either \""
- + RESULT_SUCCESS + "\" or \"" + RESULT_FAIL + "\"");
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Deploy Record.");
- }
- return null;
- }
-}
-
diff --git a/src/main/java/com/ibm/devops/dra/steps/PublishSQStep.java b/src/main/java/com/ibm/devops/dra/steps/PublishSQStep.java
deleted file mode 100644
index 995c668..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/PublishSQStep.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import hudson.Extension;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.DataBoundSetter;
-
-import javax.annotation.Nonnull;
-
-public class PublishSQStep extends AbstractDevOpsStep {
- // required parameters
- private String SQHostURL;
- private String SQAuthToken;
- private String SQProjectKey;
-
- // custom build number, optional
- private String buildNumber;
- private String environment;
-
- @DataBoundConstructor
- public PublishSQStep(String SQHostURL, String SQAuthToken, String SQProjectKey) {
-
- this.SQHostURL = SQHostURL;
- this.SQAuthToken = SQAuthToken;
- this.SQProjectKey = SQProjectKey;
- }
-
- @DataBoundSetter
- public void setEnvironment(String environment) {
- this.environment = environment;
- }
-
- @DataBoundSetter
- public void setSQHostURL(String SQHostURL) {
- this.SQHostURL = SQHostURL;
- }
-
- @DataBoundSetter
- public void setSQAuthToken(String SQAuthToken) {
- this.SQAuthToken = SQAuthToken;
- }
-
- @DataBoundSetter
- public void setSQProjectKey(String SQProjectKey) {
- this.SQProjectKey = SQProjectKey;
- }
-
- @DataBoundSetter
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public String getEnvironment() {
- return environment;
- }
-
- public String getSQHostURL() {
- return SQHostURL;
- }
-
- public String getSQAuthToken() {
- return SQAuthToken;
- }
-
- public String getSQProjectKey() {
- return SQProjectKey;
- }
-
- @Extension
- public static class DescriptorImpl extends AbstractStepDescriptorImpl {
-
- public DescriptorImpl() { super(PublishSQStepExecution.class); }
-
- @Override
- public String getFunctionName() {
- return "publishSQResults";
- }
-
- @Nonnull
- @Override
- public String getDisplayName() {
- return "Publish SonarQube test results to IBM Cloud DevOps";
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/PublishSQStepExecution.java b/src/main/java/com/ibm/devops/dra/steps/PublishSQStepExecution.java
deleted file mode 100644
index 9804123..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/PublishSQStepExecution.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import com.ibm.devops.dra.PublishSQ;
-import com.ibm.devops.dra.Util;
-import hudson.EnvVars;
-import hudson.FilePath;
-import hudson.Launcher;
-import hudson.model.Run;
-import hudson.model.TaskListener;
-import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution;
-import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
-
-import javax.inject.Inject;
-import java.io.PrintStream;
-import java.util.HashMap;
-
-import static com.ibm.devops.dra.AbstractDevOpsAction.setRequiredEnvVars;
-
-public class PublishSQStepExecution extends AbstractSynchronousNonBlockingStepExecution {
- private static final long serialVersionUID = 1L;
- @Inject
- private transient PublishSQStep step;
-
- @StepContextParameter
- private transient TaskListener listener;
- @StepContextParameter
- private transient FilePath ws;
- @StepContextParameter
- private transient Launcher launcher;
- @StepContextParameter
- private transient Run build;
- @StepContextParameter
- private transient EnvVars envVars;
-
- @Override
- protected Void run() throws Exception {
-
- PrintStream printStream = listener.getLogger();
-
- HashMap requiredEnvVars = setRequiredEnvVars(step, envVars);
-
- //check all the required env vars
- if (!Util.allNotNullOrEmpty(requiredEnvVars, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Test Result.");
- return null;
- }
-
- //check all the required parameters
- HashMap requiredParams = new HashMap<>();
- requiredParams.put("SQProjectKey", step.getSQProjectKey());
- requiredParams.put("SQHostURL", step.getSQHostURL());
- requiredParams.put("SQAuthToken", step.getSQAuthToken());
-
- if (!Util.allNotNullOrEmpty(requiredParams, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload SonarQube Test Result.");
- return null;
- }
-
- // optional build number, if user wants to set their own build number
- String buildNumber = step.getBuildNumber();
-
- PublishSQ publisher = new PublishSQ(requiredEnvVars, requiredEnvVars);
-
- if (!Util.isNullOrEmpty(buildNumber)) {
- publisher.setBuildNumber(buildNumber);
- }
- publisher.perform(build, ws, launcher, listener);
-
- return null;
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/PublishTestStep.java b/src/main/java/com/ibm/devops/dra/steps/PublishTestStep.java
deleted file mode 100644
index 6aa7948..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/PublishTestStep.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import hudson.Extension;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.DataBoundSetter;
-
-import javax.annotation.Nonnull;
-
-public class PublishTestStep extends AbstractDevOpsStep {
-
- // required parameters
- private String type;
- private String fileLocation;
- // custom build number, optional
- private String buildNumber;
-
- // optional form fields for fvt
- private String environment;
-
- @DataBoundConstructor
- public PublishTestStep(String type, String fileLocation) {
- this.type = type;
- this.fileLocation = fileLocation;
- }
-
- @DataBoundSetter
- public void setEnvironment(String environment) {
- this.environment = environment;
- }
-
- @DataBoundSetter
- public void setBuildNumber(String buildNumber) {
- this.buildNumber = buildNumber;
- }
-
- public String getBuildNumber() {
- return buildNumber;
- }
-
- public String getEnvironment() {
- return environment;
- }
-
- public String getType() {
- return type;
- }
-
- public String getFileLocation() {
- return fileLocation;
- }
-
- @Extension
- public static class DescriptorImpl extends AbstractStepDescriptorImpl {
-
- public DescriptorImpl() { super(PublishTestStepExecution.class); }
-
- @Override
- public String getFunctionName() {
- return "publishTestResult";
- }
-
- @Nonnull
- @Override
- public String getDisplayName() {
- return "Publish test result to IBM Cloud DevOps";
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/dra/steps/PublishTestStepExecution.java b/src/main/java/com/ibm/devops/dra/steps/PublishTestStepExecution.java
deleted file mode 100644
index 02d43d5..0000000
--- a/src/main/java/com/ibm/devops/dra/steps/PublishTestStepExecution.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.dra.steps;
-
-import com.ibm.devops.dra.PublishTest;
-import com.ibm.devops.dra.Util;
-import hudson.EnvVars;
-import hudson.FilePath;
-import hudson.Launcher;
-import hudson.model.Run;
-import hudson.model.TaskListener;
-import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution;
-import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
-
-import javax.inject.Inject;
-import java.io.PrintStream;
-import java.util.HashMap;
-
-import static com.ibm.devops.dra.AbstractDevOpsAction.setRequiredEnvVars;
-
-public class PublishTestStepExecution extends AbstractSynchronousNonBlockingStepExecution {
- private static final long serialVersionUID = 1L;
- @Inject
- private transient PublishTestStep step;
-
- @StepContextParameter
- private transient TaskListener listener;
- @StepContextParameter
- private transient FilePath ws;
- @StepContextParameter
- private transient Launcher launcher;
- @StepContextParameter
- private transient Run build;
- @StepContextParameter
- private transient EnvVars envVars;
-
- @Override
- protected Void run() throws Exception {
-
- PrintStream printStream = listener.getLogger();
-
- HashMap requiredEnvVars = setRequiredEnvVars(step, envVars);
-
- //check all the required env vars
- if (!Util.allNotNullOrEmpty(requiredEnvVars, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Test Result.");
- return null;
- }
-
- //check all the required parameters
- HashMap requiredParams = new HashMap<>();
- String type = step.getType();
- requiredParams.put("type", type);
- requiredParams.put("fileLocation", step.getFileLocation());
-
- // optional build number, if user wants to set their own build number
- String buildNumber = step.getBuildNumber();
- String envName = step.getEnvironment();
-
- if (!Util.allNotNullOrEmpty(requiredParams, printStream)) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to upload Test Result.");
- return null;
- }
-
- if (type.equals("unittest") || type.equals("code") || type.equals("fvt")) {
- PublishTest publishTest = new PublishTest(requiredEnvVars, requiredParams);
-
- if (!Util.isNullOrEmpty(envName)) publishTest.setEnvName(envName);
- if (!Util.isNullOrEmpty(buildNumber)) publishTest.setBuildNumber(buildNumber);
-
- publishTest.perform(build, ws, launcher, listener);
- } else {
- printStream.println("[IBM Cloud DevOps] the \"type\" in the publishTestResult should be either \"unittest\", \"code\" or \"fvt\"");
- }
-
- return null;
- }
-}
diff --git a/src/main/java/com/ibm/devops/notification/BuildListener.java b/src/main/java/com/ibm/devops/notification/BuildListener.java
deleted file mode 100644
index 089836e..0000000
--- a/src/main/java/com/ibm/devops/notification/BuildListener.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-
-
- Copyright 2016, 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification;
-
-import com.ibm.devops.dra.Util;
-import hudson.EnvVars;
-import hudson.Extension;
-import hudson.model.*;
-import hudson.model.listeners.RunListener;
-import net.sf.json.JSONObject;
-import java.io.PrintStream;
-
-@Extension
-public class BuildListener extends RunListener {
-
- public BuildListener(){
- super(AbstractBuild.class);
- }
-
- @Override
- public void onStarted(AbstractBuild r, TaskListener listener) {
- handleEvent(r, listener, "STARTED");
- }
-
- @Override
- public void onCompleted(AbstractBuild r, TaskListener listener) {
- handleEvent(r, listener, "COMPLETED");
- }
-
- @Override
- public void onFinalized(AbstractBuild r){
- handleEvent(r, TaskListener.NULL, "FINALIZED");
- }
-
- private void handleEvent(AbstractBuild r, TaskListener listener, String phase) {
- OTCNotifier notifier = EventHandler.findPublisher(r);
- PrintStream printStream = listener.getLogger();
- EnvVars envVars = EventHandler.getEnv(r, listener, printStream);
- String webhook = Util.getWebhookUrl(envVars);
- Result result = r.getResult();
-
- // OTC Notifier
- if(EventHandler.isRelevant(notifier, phase, result)) {
- String resultString = null;
- if(result != null){
- resultString = result.toString();
- }
-
- JSONObject message = MessageHandler.buildMessage(r, envVars, phase, resultString);
- MessageHandler.postToWebhook(webhook, false, message, printStream);
- }
-
- // deployable mapping
- if(EventHandler.shouldPostDeployableMappingMessage(notifier, phase, result)) {
- printStream.println("[IBM Cloud DevOps] Building Deployable Message.");
- String resultString = null;
- if(result != null){
- resultString = result.toString();
- }
-
- if (Util.validateEnvVariables(envVars, printStream)) {
- JSONObject message = MessageHandler.buildDeployableMappingMessage(envVars, printStream);
- printStream.println("[IBM Cloud DevOps] Sending Deployable Message.");
- MessageHandler.postToWebhook(webhook, true, message, printStream);
- } else {
- printStream.println("[IBM Cloud DevOps] Not sending Deployable Message due to missing required property.");
- }
- } else {
- printStream.println("[IBM Cloud DevOps] Not building Deployable Message.");
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/notification/EventHandler.java b/src/main/java/com/ibm/devops/notification/EventHandler.java
deleted file mode 100644
index aba80ac..0000000
--- a/src/main/java/com/ibm/devops/notification/EventHandler.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification;
-
-import com.ibm.devops.dra.Util;
-import hudson.EnvVars;
-import hudson.model.AbstractBuild;
-import hudson.model.Result;
-import hudson.model.TaskListener;
-import hudson.tasks.Publisher;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.List;
-
-public final class EventHandler {
- /*
- find OTCNotifer in the publisher list
- */
- public static OTCNotifier findPublisher(AbstractBuild r){
- List publisherList = r.getProject().getPublishersList().toList();
-
- //ensure that there is an OTCNotifier in the project
- for(Publisher publisher: publisherList){
- if(publisher instanceof OTCNotifier){
- return (OTCNotifier) publisher;
- }
- }
-
- return null;
- }
-
- /*
- return the build env variables
- */
- public static EnvVars getEnv(AbstractBuild r, TaskListener listener, PrintStream printStream){
- try {
- return r.getEnvironment(listener);
- } catch (IOException e) {
- printStream.println("[IBM Cloud DevOps] Exception: ");
- printStream.println("[IBM Cloud DevOps] Error: Failed to notify OTC.");
- e.printStackTrace(printStream);
- } catch (InterruptedException e) {
- printStream.println("[IBM Cloud DevOps] Exception: ");
- printStream.println("[IBM Cloud DevOps] Error: Failed to notify OTC.");
- e.printStackTrace(printStream);
- }
-
- return null;
- }
-
- /*
- Check job config to see if message should be sent.
- */
- public static boolean isRelevant(OTCNotifier notifier, String phase, Result result){
- boolean onStarted;
- boolean onCompleted;
- boolean onFinalized;
- boolean failureOnly;
-
- //Make sure OTC Notifier was found in the publisherList
- if(notifier != null){
- onStarted = notifier.getOnStarted();
- onCompleted = notifier.getOnCompleted();
- onFinalized = notifier.getOnFinalized();
- failureOnly = notifier.getFailureOnly();
-
- if(onStarted && "STARTED".equals(phase) || onCompleted && "COMPLETED".equals(phase)
- || onFinalized && "FINALIZED".equals(phase)){//check selections
- if(failureOnly && result != null && result.equals(Result.FAILURE) || !failureOnly){//check failureOnly
- return true;
- }
- }
- }
-
- return false;
- }
-
- /*
- Returns whether deployable mapping message should be sent.
- */
- public static boolean shouldPostDeployableMappingMessage(OTCNotifier notifier, String phase, Result result){
- // publish deployable mapping message only is traceability is enabled, phase is completed and build is successful
- if(notifier != null && notifier.getEnableTraceability()){
- if ("COMPLETED".equals(phase) && result.equals(Result.SUCCESS)){
- return true;
- }
- }
- return false;
- }
-}
diff --git a/src/main/java/com/ibm/devops/notification/MessageHandler.java b/src/main/java/com/ibm/devops/notification/MessageHandler.java
deleted file mode 100644
index 95fd130..0000000
--- a/src/main/java/com/ibm/devops/notification/MessageHandler.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification;
-
-import com.ibm.devops.dra.AbstractDevOpsAction;
-import com.ibm.devops.dra.Util;
-import hudson.EnvVars;
-import hudson.model.Run;
-import hudson.model.Job;
-import jenkins.model.Jenkins;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.impl.client.HttpClients;
-import java.io.IOException;
-import java.io.PrintStream;
-
-//build message that will be posted to the webhook
-public final class MessageHandler {
- public static JSONObject buildMessage(Run r, EnvVars envVars, String phase, String result){
- JSONObject message = new JSONObject();
- JSONObject build = new JSONObject();
- JSONObject scm = new JSONObject();
-
- Job job = r.getParent();
- String rootUrl = Jenkins.getInstance().getRootUrl();
-
- //setup scm
- if(envVars != null) {
- String gitCommit = envVars.get("GIT_COMMIT");
- String gitBranch = envVars.get("GIT_BRANCH");
- String gitPreviousCommit = envVars.get("GIT_PREVIOUS_COMMIT");
- String gitPreviousSuccessfulCommit = envVars.get("GIT_PREVIOUS_SUCCESSFUL_COMMIT");
- String gitUrl = envVars.get("GIT_URL");
- String gitCommitterName = envVars.get("GIT_COMMITTER_NAME");
- String gitCommitterEmail = envVars.get("GIT_COMMITTER_EMAIL");
- String gitAuthorName = envVars.get("GIT_AUTHOR_NAME");
- String gitAuthorEmail = envVars.get("GIT_AUTHOR_EMAIL");
-
- if (gitCommit != null) {
- scm.put("git_commit", gitCommit);
- }
-
- if (gitBranch != null) {
- scm.put("git_branch", gitBranch);
- }
-
- if (gitPreviousCommit != null) {
- scm.put("git_previous_commit", gitPreviousCommit);
- }
-
- if (gitPreviousSuccessfulCommit != null) {
- scm.put("git_previous_successful_commit", gitPreviousSuccessfulCommit);
- }
-
- if (gitUrl != null) {
- scm.put("git_url", gitUrl);
- }
-
- if (gitCommitterName != null) {
- scm.put("git_committer_name", gitCommitterName);
- }
-
- if (gitCommitterEmail != null) {
- scm.put("git_committer_email", gitCommitterEmail);
- }
-
- if (gitAuthorName != null) {
- scm.put("git_author_name", gitAuthorName);
- }
-
- if (gitAuthorEmail != null) {
- scm.put("git_author_email", gitAuthorEmail);
- }
- }
-
- //setup the build object
- build.put("number", r.getNumber());
- build.put("queue_id", r.getQueueId());
- build.put("phase", phase);
- build.put("url", r.getUrl());
-
- if(rootUrl != null){
- build.put("full_url", rootUrl + r.getUrl());
- } else{
- build.put("full_url", "");
- }
-
- if(result != null){
- build.put("status", result);
- }
-
- if(!"STARTED".equals(phase)) {
- build.put("duration", r.getDuration());
- }
-
- build.put("scm", scm);
-
- //setup the message
- message.put("name", job.getName());
- message.put("url", job.getUrl());
- message.put("build", build);
-
- return message;
- }
-
- //post message to webhook
- public static void postToWebhook(String webhook, boolean deployableMessage, JSONObject message, PrintStream printStream){
- //check webhook
- if(Util.isNullOrEmpty(webhook)){
- printStream.println("[IBM Cloud DevOps] IBM_CLOUD_DEVOPS_WEBHOOK_URL not set.");
- printStream.println("[IBM Cloud DevOps] Error: Failed to notify OTC.");
- } else {
- // set a 5 seconds timeout
- RequestConfig defaultRequestConfig = RequestConfig.custom()
- .setSocketTimeout(5000)
- .setConnectTimeout(5000)
- .setConnectionRequestTimeout(5000)
- .build();
- CloseableHttpClient httpClient = HttpClients.custom()
- .setDefaultRequestConfig(defaultRequestConfig)
- .build();
- HttpPost postMethod = new HttpPost(webhook);
- try {
- StringEntity data = new StringEntity(message.toString());
- postMethod.setEntity(data);
- postMethod = Proxy.addProxyInformation(postMethod);
- postMethod.addHeader("Content-Type", "application/json");
-
- if (deployableMessage) {
- postMethod.addHeader("x-create-connection", "true");
- printStream.println("[IBM Cloud DevOps] Sending Deployable Mapping message to webhook:");
- printStream.println(message);
- }
-
- CloseableHttpResponse response = httpClient.execute(postMethod);
-
- if (response.getStatusLine().toString().matches(".*2([0-9]{2}).*")) {
- printStream.println("[IBM Cloud DevOps] Message successfully posted to webhook.");
- } else {
- printStream.println("[IBM Cloud DevOps] Message failed, response status: " + response.getStatusLine());
- }
- } catch (IOException e) {
- printStream.println("[IBM Cloud DevOps] IOException, could not post to webhook:");
- e.printStackTrace(printStream);
- }
- }
- }
-
- public static JSONObject buildDeployableMappingMessage(EnvVars envVars, PrintStream printStream){
- String environment = null;
- // for debugging purpose only, uncomment the line below
- // environment = "dev"; // to target YS1
- try {
- JSONObject deployableMappingMessage;
- // API
- String apiUrl= AbstractDevOpsAction.chooseTargetAPI(environment);
-
- // get bluemix token first
- String userId= Util.getUser(envVars);
- String pwd= Util.getPassword(envVars);
-
- String bluemixToken = AbstractDevOpsAction.getBluemixToken(userId, pwd, apiUrl);
-
- // org details
- JSONObject org = new JSONObject();
- String orgName = Util.getOrg(envVars);
- org.put("Name" , orgName);
- String orgId= AbstractDevOpsAction.getOrgId(bluemixToken, orgName, environment, false);
- org.put("Guid" , orgId);
-
- // space details
- JSONObject space = new JSONObject();
- String spaceName = Util.getSpace(envVars);
- space.put("Name" , spaceName);
- String spaceId= AbstractDevOpsAction.getSpaceId(bluemixToken, spaceName, environment, false);
- space.put("Guid" , spaceId);
-
- // app details
- JSONObject app = new JSONObject();
- String appName = Util.getAppName(envVars);
- app.put("Name" , appName);
- String appId= AbstractDevOpsAction.getAppId(bluemixToken, appName, orgName, spaceName, environment, false);
- app.put("Guid" , appId);
-
- // Git
- JSONArray gitData= MessageUtil.buildGitData(envVars, printStream);
-
- // format deployable message
- deployableMappingMessage = MessageUtil.formatDeployableMappingMessage(org, space, app, apiUrl, gitData, printStream);
-
- return deployableMappingMessage;
-
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Unexpected Exception encountered while building deployable message:");
- e.printStackTrace(printStream);
- }
-
- return new JSONObject();
- }
-}
diff --git a/src/main/java/com/ibm/devops/notification/MessageUtil.java b/src/main/java/com/ibm/devops/notification/MessageUtil.java
deleted file mode 100644
index 8bccbcd..0000000
--- a/src/main/java/com/ibm/devops/notification/MessageUtil.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification;
-
-import com.ibm.devops.dra.Util;
-import hudson.EnvVars;
-import java.io.PrintStream;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
-
-/**
- * Message Utilities functions
- */
-
-public class MessageUtil {
-
- public static JSONArray buildGitData(EnvVars envVars, PrintStream printStream) {
- try {
- String gitUrl = Util.getGitRepoUrl(envVars);
- String gitBranch = Util.getGitBranch(envVars);
- String gitCommit = Util.getGitCommit(envVars);
-
- JSONObject gitInfo = new JSONObject();
- gitInfo.put("GitURL" , gitUrl);
- gitInfo.put("GitBranch" , gitBranch);
- gitInfo.put("GitCommitID" , gitCommit);
-
- JSONArray gitData = new JSONArray();
- gitData.add(gitInfo);
-
- return gitData;
-
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to build Git data.");
- e.printStackTrace(printStream);
- throw e;
- }
- }
-
- public static JSONObject formatDeployableMappingMessage(JSONObject org, JSONObject space, JSONObject app, String apiUrl, JSONArray gitData, PrintStream printStream) {
- try {
- JSONObject deployableMappingMessage = new JSONObject();
- deployableMappingMessage.put("Org" , org);
- deployableMappingMessage.put("Space" , space);
- deployableMappingMessage.put("App" , app);
- deployableMappingMessage.put("ApiEndpoint" , apiUrl);
- deployableMappingMessage.put("Method" , "POST");
- deployableMappingMessage.put("GitData" , gitData);
- return deployableMappingMessage;
-
- } catch (Exception e) {
- printStream.println("[IBM Cloud DevOps] Error: Failed to build Deployable Mapping Message.");
- e.printStackTrace(printStream);
- throw e;
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/notification/OTCNotifier.java b/src/main/java/com/ibm/devops/notification/OTCNotifier.java
deleted file mode 100644
index a75793e..0000000
--- a/src/main/java/com/ibm/devops/notification/OTCNotifier.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification;
-
-import hudson.Extension;
-import hudson.Launcher;
-import hudson.model.AbstractBuild;
-import hudson.model.AbstractProject;
-import hudson.model.BuildListener;
-import hudson.tasks.BuildStepDescriptor;
-import hudson.tasks.BuildStepMonitor;
-import hudson.tasks.Notifier;
-import hudson.tasks.Publisher;
-import org.kohsuke.stapler.DataBoundConstructor;
-import java.io.IOException;
-
-public class OTCNotifier extends Notifier {
- private boolean onStarted;
- private boolean onCompleted;
- private boolean onFinalized;
- private boolean failureOnly;
- private boolean enableTraceability;
-
- /*
- The paramater names in @DataBoundConstructor need to match the fields in config.jelly exactly
- */
- @DataBoundConstructor
- public OTCNotifier(boolean onStarted,
- boolean onCompleted,
- boolean onFinalized,
- boolean failureOnly,
- boolean enableTraceability
- ){
- this.onStarted = onStarted;
- this.onCompleted = onCompleted;
- this.onFinalized = onFinalized;
- this.failureOnly = failureOnly;
- this.enableTraceability = enableTraceability;
- }
-
- /*
- These methods are called by jenkins to populate the per-job config fields
- */
- public Boolean getOnStarted(){
- return this.onStarted;
- }
-
- public Boolean getOnCompleted(){
- return this.onCompleted;
- }
-
- public Boolean getOnFinalized(){
- return this.onFinalized;
- }
-
- public Boolean getFailureOnly(){
- return this.failureOnly;
- }
-
- public Boolean getEnableTraceability(){
- return this.enableTraceability;
- }
-
- public BuildStepMonitor getRequiredMonitorService() {
- return BuildStepMonitor.NONE;
- }
-
- @Override
- public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
- return true;
- }
-
- @Override
- public DescriptorImpl getDescriptor() {
- return (DescriptorImpl)super.getDescriptor();
- }
-
- /*
- The descriptor allows global configs for your plugin, this class will be passed to every instance of the plugin.
- */
- @Extension // This indicates to Jenkins that this is an implementation of an extension point.
- public static final class DescriptorImpl extends BuildStepDescriptor {
- @Override
- public String getDisplayName() {
- return "Notify OTC";//This is the plugin name in the config
- }
-
- public boolean isApplicable(Class extends AbstractProject> aClass) {
- return true; //It is always ok for someone to add this as a build step
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/ibm/devops/notification/steps/DeployableMappingNotificationExecution.java b/src/main/java/com/ibm/devops/notification/steps/DeployableMappingNotificationExecution.java
deleted file mode 100644
index 0d38910..0000000
--- a/src/main/java/com/ibm/devops/notification/steps/DeployableMappingNotificationExecution.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification.steps;
-
-import com.ibm.devops.dra.Util;
-import com.ibm.devops.notification.MessageHandler;
-import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution;
-import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
-import javax.inject.Inject;
-import hudson.EnvVars;
-import hudson.model.Run;
-import hudson.model.TaskListener;
-import net.sf.json.JSONObject;
-
-
-import java.io.PrintStream;
-
-public class DeployableMappingNotificationExecution extends AbstractSynchronousNonBlockingStepExecution {
- private static final long serialVersionUID = 1L;
- @Inject
- private transient DeployableMappingNotificationStep step;
- @StepContextParameter
- private transient TaskListener listener;
- @StepContextParameter
- private transient Run build;
- @StepContextParameter
- private transient EnvVars envVars;
-
- @Override
- protected Void run() throws Exception {
- PrintStream printStream = listener.getLogger();
- String webhookUrl;
-
- if(Util.isNullOrEmpty(step.getWebhookUrl())){
- webhookUrl = Util.getWebhookUrl(envVars);
- } else {
- webhookUrl = step.getWebhookUrl();
- }
-
- String status = step.getStatus().trim();
- //check all the required env vars
- if (!Util.allNotNullOrEmpty(status)) {
- printStream.println("[IBM Cloud DevOps] Required parameter null or empty.");
- printStream.println("[IBM Cloud DevOps] Error: Failed to notify OTC.");
- return null;
- }
-
- if ("SUCCESS".equals(status)) { // send deployable mapping message on for successful builds
- JSONObject message = MessageHandler.buildDeployableMappingMessage(envVars, printStream);
- MessageHandler.postToWebhook(webhookUrl, true, message, printStream);
- }
- return null;
- }
-}
diff --git a/src/main/java/com/ibm/devops/notification/steps/DeployableMappingNotificationStep.java b/src/main/java/com/ibm/devops/notification/steps/DeployableMappingNotificationStep.java
deleted file mode 100644
index 2d479ab..0000000
--- a/src/main/java/com/ibm/devops/notification/steps/DeployableMappingNotificationStep.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification.steps;
-
-import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
-import hudson.Extension;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.DataBoundSetter;
-
-import javax.annotation.Nonnull;
-
-public class DeployableMappingNotificationStep extends AbstractStepImpl {
- //required parameter to support pipeline script
- private String status;
-
- //option parameters
- private String webhookUrl;
-
- @DataBoundConstructor
- public DeployableMappingNotificationStep(String status){
- this.status = status;
- }
-
- @DataBoundSetter
- public void setWebhookUrl(String webhookUrl){
- this.webhookUrl = webhookUrl;
- }
-
- public String getWebhookUrl(){
- return this.webhookUrl;
- }
-
- public String getStatus(){
- return this.status;
- }
-
- @Extension
- public static class DescriptorImpl extends AbstractStepDescriptorImpl {
- public DescriptorImpl() { super(DeployableMappingNotificationExecution.class); }
-
- @Override
- public String getFunctionName() {
- return "sendDeployableMessage";
- }
-
- @Nonnull
- @Override
- public String getDisplayName() {
- return "Send deployable mapping message to OTC";
- }
- }
-}
diff --git a/src/main/java/com/ibm/devops/notification/steps/OTCNotificationExecution.java b/src/main/java/com/ibm/devops/notification/steps/OTCNotificationExecution.java
deleted file mode 100644
index 185f627..0000000
--- a/src/main/java/com/ibm/devops/notification/steps/OTCNotificationExecution.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification.steps;
-
-import com.ibm.devops.dra.Util;
-import com.ibm.devops.notification.MessageHandler;
-import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution;
-import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
-import javax.inject.Inject;
-import hudson.EnvVars;
-import hudson.model.Run;
-import hudson.model.TaskListener;
-import net.sf.json.JSONObject;
-
-
-import java.io.PrintStream;
-
-public class OTCNotificationExecution extends AbstractSynchronousNonBlockingStepExecution {
- private static final long serialVersionUID = 1L;
- @Inject
- private transient OTCNotificationStep step;
- @StepContextParameter
- private transient TaskListener listener;
- @StepContextParameter
- private transient Run build;
- @StepContextParameter
- private transient EnvVars envVars;
-
- @Override
- protected Void run() throws Exception {
- String stageName = step.getStageName().trim();
- String status = step.getStatus().trim();
- PrintStream printStream = listener.getLogger();
- String webhookUrl;
-
- if(Util.isNullOrEmpty(step.getWebhookUrl())){
- webhookUrl = Util.getWebhookUrl(envVars);
- } else {
- webhookUrl = step.getWebhookUrl();
- }
-
- //check all the required env vars
- if (!Util.allNotNullOrEmpty(stageName, status)) {
- printStream.println("[IBM Cloud DevOps] Required parameter null or empty.");
- printStream.println("[IBM Cloud DevOps] Error: Failed to notify OTC.");
- return null;
- }
-
- JSONObject message = MessageHandler.buildMessage(build, envVars, stageName, status);
- MessageHandler.postToWebhook(webhookUrl, false, message, printStream);
-
- return null;
- }
-}
diff --git a/src/main/java/com/ibm/devops/notification/steps/OTCNotificationStep.java b/src/main/java/com/ibm/devops/notification/steps/OTCNotificationStep.java
deleted file mode 100644
index 34f9409..0000000
--- a/src/main/java/com/ibm/devops/notification/steps/OTCNotificationStep.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-
-
- Copyright 2017 IBM Corporation
-
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
- */
-
-package com.ibm.devops.notification.steps;
-
-import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
-import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
-import hudson.Extension;
-import org.kohsuke.stapler.DataBoundConstructor;
-import org.kohsuke.stapler.DataBoundSetter;
-
-import javax.annotation.Nonnull;
-
-public class OTCNotificationStep extends AbstractStepImpl {
- //required parameter to support pipeline script
- private String status;
- private String stageName;
-
- //option parameters
- private String webhookUrl;
-
- @DataBoundConstructor
- public OTCNotificationStep(String stageName, String status){
- this.stageName = stageName;
- this.status = status;
- }
-
- @DataBoundSetter
- public void setWebhookUrl(String webhookUrl){
- this.webhookUrl = webhookUrl;
- }
-
- public String getWebhookUrl(){
- return this.webhookUrl;
- }
-
- public String getStatus(){
- return this.status;
- }
-
- public String getStageName(){
- return this.stageName;
- }
-
- @Extension
- public static class DescriptorImpl extends AbstractStepDescriptorImpl {
- public DescriptorImpl() { super(OTCNotificationExecution.class); }
-
- @Override
- public String getFunctionName() {
- return "notifyOTC";
- }
-
- @Nonnull
- @Override
- public String getDisplayName() {
- return "Send notification to OTC";
- }
- }
-}
diff --git a/src/main/resources/com/ibm/devops/dra/DevOpsGlobalConfiguration/config.jelly b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/config.jelly
similarity index 76%
rename from src/main/resources/com/ibm/devops/dra/DevOpsGlobalConfiguration/config.jelly
rename to src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/config.jelly
index 5cbfcdb..205ebad 100644
--- a/src/main/resources/com/ibm/devops/dra/DevOpsGlobalConfiguration/config.jelly
+++ b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/config.jelly
@@ -13,7 +13,7 @@
-->
-
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/com/ibm/devops/dra/DevOpsGlobalConfiguration/help-consoleUrl.html b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-consoleUrl.html
similarity index 100%
rename from src/main/resources/com/ibm/devops/dra/DevOpsGlobalConfiguration/help-consoleUrl.html
rename to src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-consoleUrl.html
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-buildNumber.html b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-instanceName.html
similarity index 79%
rename from src/main/resources/com/ibm/devops/dra/EvaluateGate/help-buildNumber.html
rename to src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-instanceName.html
index 1f71cd5..f6a772d 100644
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-buildNumber.html
+++ b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-instanceName.html
@@ -1,7 +1,7 @@
- Specify the number for external builds. You can define this number as an environment variable. .
+ Specify the instance name of this Jenkins server. See Getting
+started with Continuous Release documentation.
+
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-buildJobName.html b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-syncId.html
similarity index 79%
rename from src/main/resources/com/ibm/devops/dra/EvaluateGate/help-buildJobName.html
rename to src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-syncId.html
index 4a4049b..2448609 100644
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-buildJobName.html
+++ b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-syncId.html
@@ -1,7 +1,7 @@
- Enter the name of the build job that triggers this test job. You can use an environment variable, such as $BUILD_JOB.
+ Specify your DevOps Connect sync ID (requires a server restart). See Getting
+started with Continuous Release documentation.
+
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-additionalBuildInfo.html b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-syncToken.html
similarity index 78%
rename from src/main/resources/com/ibm/devops/dra/EvaluateGate/help-additionalBuildInfo.html
rename to src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-syncToken.html
index 1b141d8..600a6eb 100644
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-additionalBuildInfo.html
+++ b/src/main/resources/com/ibm/devops/connect/DevOpsGlobalConfiguration/help-syncToken.html
@@ -1,7 +1,7 @@
- Select this check box if the deployed app is not built in Jenkins.
+ Specify your DevOps Connect sync token (requires a server restart). See Getting
+started with Continuous Release documentation.
+
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/BuildPublisherAction/summary.jelly b/src/main/resources/com/ibm/devops/dra/BuildPublisherAction/summary.jelly
deleted file mode 100755
index e1afa0a..0000000
--- a/src/main/resources/com/ibm/devops/dra/BuildPublisherAction/summary.jelly
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
IBM Cloud DevOps
-
-
- Please click here to view the build status of all application
-
-
- Type a name for the application that information is being uploaded for. Use this application name when you configure DevOps Insights gates. You can use an environment variable, such as $APP_NAME.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-credentialsId.html b/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-credentialsId.html
deleted file mode 100644
index 941d6ed..0000000
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-credentialsId.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a Bluemix ID from the menu. If no Bluemix IDs are in the menu, click Add to add one. Click Test Connection to verify the selected credentials.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-envName.html b/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-envName.html
deleted file mode 100644
index ffc39b0..0000000
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-envName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the name of the environment that this job deploys to. If this environment is your staging environment, type "STAGING." If this environment is your production requirement, type "PRODUCTION." If you do not specify staging and production environments, DevOps Insights cannot completely analyze your project.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-orgName.html b/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-orgName.html
deleted file mode 100644
index f8feb78..0000000
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-orgName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the name of the Bluemix organization that you want to use. You can type the name here or use an environment variable, such as $ORG_NAME, that is defined elsewhere.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-policyName.html b/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-policyName.html
deleted file mode 100644
index cc57ab5..0000000
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-policyName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select the policy that you want this gate to enforce. You can create more policies in DevOps Insights.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-toolchainName.html b/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-toolchainName.html
deleted file mode 100644
index 42b2702..0000000
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-toolchainName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a toolchain. If you have not created a toolchain yet, create one here.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-willDisrupt.html b/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-willDisrupt.html
deleted file mode 100644
index cff206c..0000000
--- a/src/main/resources/com/ibm/devops/dra/EvaluateGate/help-willDisrupt.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select this check box to cancel associated Jenkins builds when this gate fails.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/GatePublisherAction/summary.jelly b/src/main/resources/com/ibm/devops/dra/GatePublisherAction/summary.jelly
deleted file mode 100755
index 9e7861b..0000000
--- a/src/main/resources/com/ibm/devops/dra/GatePublisherAction/summary.jelly
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
IBM Cloud DevOps
-
Policy Name: ${it.policyName}
-
Decision: ${it.decision}
-
- Click here to view the Gate Evaluation Report.
-
-
- Click here to view the Deployment Risk Dashboard.
-
- Select this check box if you want to set your own build number.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-applicationName.html b/src/main/resources/com/ibm/devops/dra/PublishBuild/help-applicationName.html
deleted file mode 100644
index 123f11f..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-applicationName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type a name for the application that information is being uploaded for. Use this application name when you configure DevOps Insights gates. You can use an environment variable, such as $APP_NAME.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-buildNumber.html b/src/main/resources/com/ibm/devops/dra/PublishBuild/help-buildNumber.html
deleted file mode 100644
index 6ca7fb8..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-buildNumber.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Specify the custom build number for this job. You can define this number as an environment variable.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-credentialsId.html b/src/main/resources/com/ibm/devops/dra/PublishBuild/help-credentialsId.html
deleted file mode 100644
index cd32d9a..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-credentialsId.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a Bluemix ID from the menu. If no Bluemix IDs are in the menu, click Add to add one. Click Test Connection to verify the selected credentials.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-orgName.html b/src/main/resources/com/ibm/devops/dra/PublishBuild/help-orgName.html
deleted file mode 100644
index f8feb78..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-orgName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the name of the Bluemix organization that you want to use. You can type the name here or use an environment variable, such as $ORG_NAME, that is defined elsewhere.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-toolchainName.html b/src/main/resources/com/ibm/devops/dra/PublishBuild/help-toolchainName.html
deleted file mode 100644
index 42b2702..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishBuild/help-toolchainName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a toolchain. If you have not created a toolchain yet, create one here.
-
- Select this check box if you want to set your own build number
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-applicationName.html b/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-applicationName.html
deleted file mode 100644
index 123f11f..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-applicationName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type a name for the application that information is being uploaded for. Use this application name when you configure DevOps Insights gates. You can use an environment variable, such as $APP_NAME.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-applicationUrl.html b/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-applicationUrl.html
deleted file mode 100644
index 3c86d17..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-applicationUrl.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Optional: If this is a web application, enter its URL. You can use an environment variable, such as $APP_URL.
-
- Specify the custom build number for this job. You can define this number as an environment variable.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-credentialsId.html b/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-credentialsId.html
deleted file mode 100644
index cd32d9a..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-credentialsId.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a Bluemix ID from the menu. If no Bluemix IDs are in the menu, click Add to add one. Click Test Connection to verify the selected credentials.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-environmentName.html b/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-environmentName.html
deleted file mode 100644
index 731ad3a..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-environmentName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the name of the environment that this job deploys to. If this environment is your staging environment, type "STAGING." If this environment is your production requirement, type "PRODUCTION." If you do not specify staging and production environments, DevOps Insights cannot completely analyze your project.
-
- Type the name of the Bluemix organization that you want to use. You can type the name here or use an environment variable, such as $ORG_NAME, that is defined elsewhere.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-toolchainName.html b/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-toolchainName.html
deleted file mode 100644
index 42b2702..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishDeploy/help-toolchainName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a toolchain. If you have not created a toolchain yet, create one here.
-
- Enter your API token that SonarQube generated for you.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-SQHostName.html b/src/main/resources/com/ibm/devops/dra/PublishSQ/help-SQHostName.html
deleted file mode 100644
index f669942..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-SQHostName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the hostname of the server that your SonarQube instance runs on. Do not enter a trailing slash.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-SQProjectKey.html b/src/main/resources/com/ibm/devops/dra/PublishSQ/help-SQProjectKey.html
deleted file mode 100644
index cc3785b..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-SQProjectKey.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the key of the SonarQube project that you wish to scan.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-additionalBuildInfo.html b/src/main/resources/com/ibm/devops/dra/PublishSQ/help-additionalBuildInfo.html
deleted file mode 100644
index 999c790..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-additionalBuildInfo.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select this check box if you want to set your own build number
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-applicationName.html b/src/main/resources/com/ibm/devops/dra/PublishSQ/help-applicationName.html
deleted file mode 100644
index 5faec8c..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-applicationName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type a name for the application that information is being uploaded for. Use this application name when you configure DevOps Insights gates. You can use an environment variable, such as $APP_NAME.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-buildJobName.html b/src/main/resources/com/ibm/devops/dra/PublishSQ/help-buildJobName.html
deleted file mode 100644
index 08847b7..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-buildJobName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Enter the name of the build job that triggers this test job. You can use an environment variable, such as $BUILD_JOB.
-
- Specify the custom build number for this job. You can define this number as an environment variable.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-credentialsId.html b/src/main/resources/com/ibm/devops/dra/PublishSQ/help-credentialsId.html
deleted file mode 100644
index 8fef5fe..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-credentialsId.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a Bluemix ID from the menu. If no Bluemix IDs are in the menu, click Add to add one. Click Test Connection to verify the selected credentials.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-orgName.html b/src/main/resources/com/ibm/devops/dra/PublishSQ/help-orgName.html
deleted file mode 100644
index dfe4277..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-orgName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the name of the Bluemix organization that you want to use. You can type the name here or use an environment variable, such as $ORG_NAME, that is defined elsewhere.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-toolchainName.html b/src/main/resources/com/ibm/devops/dra/PublishSQ/help-toolchainName.html
deleted file mode 100644
index 0aec8dc..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishSQ/help-toolchainName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a toolchain. If you have not created a toolchain yet, create one here.
-
- Select this check box if you want to set your own build number
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalContents.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalContents.html
deleted file mode 100644
index ea3336e..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalContents.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- Enter the test result file location relative to the root directory. The result file must contain results in the format that you selected for the metric type. This field supports wildcards and environment variables.
- If you leave this field empty, DevOps Insights generates a simple test report that is based on job status.
- Mocha, KarmaMocha, Istanbul, and BlanketJS test results must be in the JSON format.
- xUnit test results must be in the XML format.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalLifecycleStage.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalLifecycleStage.html
deleted file mode 100644
index bb6b5c3..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalLifecycleStage.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- Select the type of test. Your tests must correspond to rules in policies.
-
- Supported formats:
-
Code coverage: Istanbul, BlanketJS
-
Unit and functional verification tests: Mocha, xUnit, and Karma Mocha
-
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalUpload.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalUpload.html
deleted file mode 100644
index 5702e51..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-additionalUpload.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Optional: You can upload another test result file and select another metric type in this job.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-applicationName.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-applicationName.html
deleted file mode 100644
index 3f5adfd..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-applicationName.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- Type a name for the application that information is being uploaded for. Use this application name when you configure DevOps Insights gates. You can use an environment variable, such as $APP_NAME.
-
- Enter the name of the build job that triggers this test job. You can use an environment variable, such as $BUILD_JOB.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-buildNumber.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-buildNumber.html
deleted file mode 100644
index 6ca7fb8..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-buildNumber.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Specify the custom build number for this job. You can define this number as an environment variable.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-contents.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-contents.html
deleted file mode 100644
index ea3336e..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-contents.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
- Enter the test result file location relative to the root directory. The result file must contain results in the format that you selected for the metric type. This field supports wildcards and environment variables.
- If you leave this field empty, DevOps Insights generates a simple test report that is based on job status.
- Mocha, KarmaMocha, Istanbul, and BlanketJS test results must be in the JSON format.
- xUnit test results must be in the XML format.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-credentialsId.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-credentialsId.html
deleted file mode 100644
index cd32d9a..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-credentialsId.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a Bluemix ID from the menu. If no Bluemix IDs are in the menu, click Add to add one. Click Test Connection to verify the selected credentials.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-envName.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-envName.html
deleted file mode 100644
index c89fb18..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-envName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the name of the deployment environment where the tests are run. This name must match the environment name that is used in upstream test or deployment information upload jobs, such as "STAGING" or "PRODUCTION."
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-environment.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-environment.html
deleted file mode 100644
index 4416bf6..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-environment.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Choose the environment that the test runs on. If the test runs during the build process, click Build environment.>. If the test runs on a deployed application, click Deploy environment and enter the environment name.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-lifecycleStage.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-lifecycleStage.html
deleted file mode 100644
index bb6b5c3..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-lifecycleStage.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- Select the type of test. Your tests must correspond to rules in policies.
-
- Supported formats:
-
Code coverage: Istanbul, BlanketJS
-
Unit and functional verification tests: Mocha, xUnit, and Karma Mocha
-
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-orgName.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-orgName.html
deleted file mode 100644
index f8feb78..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-orgName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Type the name of the Bluemix organization that you want to use. You can type the name here or use an environment variable, such as $ORG_NAME, that is defined elsewhere.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-policyName.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-policyName.html
deleted file mode 100644
index 5875757..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-policyName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- To evaluate test results in this job, select this check box and select a policy. The job uploads information and acts as a gate. You can create more policies in DevOps Insights.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/dra/PublishTest/help-toolchainName.html b/src/main/resources/com/ibm/devops/dra/PublishTest/help-toolchainName.html
deleted file mode 100644
index 42b2702..0000000
--- a/src/main/resources/com/ibm/devops/dra/PublishTest/help-toolchainName.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Select a toolchain. If you have not created a toolchain yet, create one here.
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/notification/OTCNotifier/config.jelly b/src/main/resources/com/ibm/devops/notification/OTCNotifier/config.jelly
deleted file mode 100644
index b587e69..0000000
--- a/src/main/resources/com/ibm/devops/notification/OTCNotifier/config.jelly
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/com/ibm/devops/notification/OTCNotifier/help.html b/src/main/resources/com/ibm/devops/notification/OTCNotifier/help.html
deleted file mode 100644
index 4f7de10..0000000
--- a/src/main/resources/com/ibm/devops/notification/OTCNotifier/help.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- Please create a String Parameter named "IBM_CLOUD_DEVOPS_WEBHOOK_URL" and set the default value to the webhook that you'd like to send messages to.
-
-
-
- Select Track deployment of code changes check box to track the deployment of code changes by creating tags, labels and comments on commits, pull requests and referenced issues.
-