From 1743fa77f12e3038712dc808b6f2480efebf8fa7 Mon Sep 17 00:00:00 2001 From: Bir Sikander Date: Wed, 28 Jul 2021 21:03:20 +0530 Subject: [PATCH 1/2] updating source importing husdon.util.secret --- .../LeapworkJenkinsBridgeBuilder.java | 800 +++++++++--------- 1 file changed, 417 insertions(+), 383 deletions(-) diff --git a/src/main/java/com/Leapwork/Leapwork_plugin/LeapworkJenkinsBridgeBuilder.java b/src/main/java/com/Leapwork/Leapwork_plugin/LeapworkJenkinsBridgeBuilder.java index fcb5cde..72bacb4 100644 --- a/src/main/java/com/Leapwork/Leapwork_plugin/LeapworkJenkinsBridgeBuilder.java +++ b/src/main/java/com/Leapwork/Leapwork_plugin/LeapworkJenkinsBridgeBuilder.java @@ -1,5 +1,6 @@ package com.Leapwork.Leapwork_plugin; +import hudson.util.Secret; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -36,386 +37,419 @@ import jenkins.tasks.SimpleBuildStep; import net.sf.json.JSONObject; -public class LeapworkJenkinsBridgeBuilder extends Builder implements SimpleBuildStep { - - private final String leapworkHostname; - private final String leapworkPort; - private final String leapworkAccessKey; - private String leapworkDelay; - private String leapworkDoneStatusAs; - private String leapworkReport; - private final String leapworkSchIds; - private final String leapworkSchNames; - private boolean leapworkWritePassedFlowKeyFrames; - private String leapworkScheduleVariables; - - private static PluginHandler pluginHandler = PluginHandler.getInstance(); - - // Fields in config.jelly must match the parameter names in the "DataBoundConstructor" - @DataBoundConstructor - public LeapworkJenkinsBridgeBuilder(String leapworkHostname,String leapworkPort, String leapworkAccessKey, String leapworkDelay, String leapworkDoneStatusAs, String leapworkReport, String leapworkSchNames, String leapworkSchIds/*, boolean leapworkWritePassedFlowKeyFrames */) - { - - this.leapworkHostname = leapworkHostname; - this.leapworkPort = leapworkPort; - this.leapworkAccessKey = leapworkAccessKey; - this.leapworkDelay = leapworkDelay; - this.leapworkDoneStatusAs = leapworkDoneStatusAs; - this.leapworkReport = leapworkReport; - this.leapworkSchIds = leapworkSchIds; - this.leapworkSchNames = leapworkSchNames; - //this.leapworkWritePassedFlowKeyFrames = leapworkWritePassedFlowKeyFrames; - } - - @DataBoundSetter - public void setLeapworkReport(String report) { this.leapworkReport = report; } - - @DataBoundSetter - public void setLeapworkDoneStatusAs(String doneStatusAs) { this.leapworkDoneStatusAs = doneStatusAs;} - - @DataBoundSetter - public void setLeapworkDelay(String leapworkDelay) { this.leapworkDelay = leapworkDelay;} - - @DataBoundSetter - public void setLeapworkWritePassedFlowKeyFrames(boolean leapworkWritePassedFlowKeyFrames) { this.leapworkWritePassedFlowKeyFrames = leapworkWritePassedFlowKeyFrames;} - - @DataBoundSetter - public void setLeapworkScheduleVariables(String leapworkScheduleVariables) { this.leapworkScheduleVariables = leapworkScheduleVariables;} - - public String getLeapworkHostname() { return leapworkHostname;} - public String getLeapworkPort() { return leapworkPort;} - public String getLeapworkAccessKey() { return leapworkAccessKey;} - public String getLeapworkDelay() { return leapworkDelay;} - public String getLeapworkSchNames() { return leapworkSchNames;} - public String getLeapworkSchIds() { return leapworkSchIds;} - public String getLeapworkDoneStatusAs() { return leapworkDoneStatusAs;} - public String getLeapworkReport() { return leapworkReport;} - public boolean isLeapworkWritePassedFlowKeyFrames() {return leapworkWritePassedFlowKeyFrames;} - public String getLeapworkScheduleVariables() {return leapworkScheduleVariables;} - - //@Override - public void perform(final Run build, FilePath workspace, Launcher launcher, final TaskListener listener) throws IOException, InterruptedException { - - EnvVars env = build.getEnvironment(listener); - ArrayList invalidSchedules = new ArrayList<>(); - - String workspacePath = pluginHandler.getWorkSpaceSafe(workspace,env); - this.leapworkReport = pluginHandler.getReportFileName(this.getLeapworkReport(),DescriptorImpl.DEFAULT_REPORT_NAME); - printPluginInputs(listener, workspacePath); - - ArrayList rawScheduleList = pluginHandler.getRawScheduleList(leapworkSchIds, leapworkSchNames); - String controllerApiHttpAddress = pluginHandler.getControllerApiHttpAdderess(leapworkHostname, leapworkPort, listener); - - int timeDelay = pluginHandler.getTimeDelay(leapworkDelay, listener); - boolean isDoneStatusAsSuccess = pluginHandler.isDoneStatusAsSuccess(leapworkDoneStatusAs); - boolean writePassedKeyframes = isLeapworkWritePassedFlowKeyFrames(); - - String scheduleVariablesRequestPart = pluginHandler.getScheduleVariablesRequestPart(getLeapworkScheduleVariables(),listener); - - try( AsyncHttpClient mainClient = new AsyncHttpClient()) - { - - //Get schedule titles (or/and ids in case of pipeline) - LinkedHashMap schedulesIdTitleHashMap = pluginHandler.getSchedulesIdTitleHashMap(mainClient, leapworkAccessKey, controllerApiHttpAddress,rawScheduleList, listener,invalidSchedules); - rawScheduleList.clear();//don't need that anymore - - if(schedulesIdTitleHashMap.isEmpty()) - { - throw new Exception(Messages.NO_SCHEDULES); - } - - List schIdsList = new ArrayList<>(schedulesIdTitleHashMap.keySet()); - LinkedHashMap resultsMap = new LinkedHashMap<>(); - - ListIterator iter = schIdsList.listIterator(); - while( iter.hasNext()) - { - - UUID schId = iter.next(); - String schTitle = schedulesIdTitleHashMap.get(schId); - LeapworkRun run = new LeapworkRun(schId.toString(),schTitle); - - UUID runId = pluginHandler.runSchedule(mainClient,controllerApiHttpAddress, leapworkAccessKey, schId, schTitle, listener, run,scheduleVariablesRequestPart); - if(runId != null) - { - resultsMap.put(runId,run); - CollectScheduleRunResults(controllerApiHttpAddress,leapworkAccessKey,runId,schTitle,timeDelay,isDoneStatusAsSuccess,writePassedKeyframes,run,listener); - } - else - resultsMap.put(UUID.randomUUID(),run); - - iter.remove(); - - } - - schIdsList.clear(); - schedulesIdTitleHashMap.clear(); - RunCollection buildResult = new RunCollection(); - - if (invalidSchedules.size() > 0) - { - listener.getLogger().println(Messages.INVALID_SCHEDULES); - - for (InvalidSchedule invalidSchedule : invalidSchedules) - { - listener.getLogger().println(String.format("%1$s: %2$s",invalidSchedule.getName(),invalidSchedule.getStackTrace())); - LeapworkRun notFoundSchedule = new LeapworkRun(invalidSchedule.getName()); - RunItem invalidRunItem = new RunItem("Error","Error",0,invalidSchedule.getStackTrace(),invalidSchedule.getName()); - notFoundSchedule.runItems.add(invalidRunItem); - notFoundSchedule.setError(invalidSchedule.getStackTrace()); - buildResult.leapworkRuns.add(notFoundSchedule); - } - - } - - List resultRuns = new ArrayList<>(resultsMap.values()); - listener.getLogger().println(Messages.TOTAL_SEPARATOR); - - for (LeapworkRun run : resultRuns) - { - buildResult.leapworkRuns.add(run); - - buildResult.addFailedTests(run.getFailed()); - buildResult.addPassedTests(run.getPassed()); - buildResult.addErrors(run.getErrors()); - run.setTotal(run.getPassed() + run.getFailed()); - buildResult.addTotalTime(run.getTime()); - listener.getLogger().println(String.format(Messages.SCHEDULE_TITLE,run.getScheduleTitle(),run.getScheduleId())); - listener.getLogger().println(String.format(Messages.CASES_PASSED,run.getPassed())); - listener.getLogger().println(String.format(Messages.CASES_FAILED,run.getFailed())); - listener.getLogger().println(String.format(Messages.CASES_ERRORED,run.getErrors())); - } - buildResult.setTotalTests(buildResult.getFailedTests() + buildResult.getPassedTests()); - - listener.getLogger().println(Messages.TOTAL_SEPARATOR); - listener.getLogger().println(String.format(Messages.TOTAL_CASES_PASSED,buildResult.getPassedTests())); - listener.getLogger().println(String.format(Messages.TOTAL_CASES_FAILED,buildResult.getFailedTests())); - listener.getLogger().println(String.format(Messages.TOTAL_CASES_ERROR,buildResult.getErrors())); - - pluginHandler.createJUnitReport(workspace,leapworkReport,listener,buildResult); - - if (buildResult.getErrors() > 0 || buildResult.getFailedTests() > 0 || invalidSchedules.size() > 0) { - if(buildResult.getErrors() > 0) - listener.getLogger().println(Messages.ERROR_NOTIFICATION); - listener.getLogger().println("FAILURE"); - build.setResult(Result.FAILURE); - } - else { - listener.getLogger().println("SUCCESS"); - build.setResult(Result.SUCCESS); - } - - listener.getLogger().println(Messages.PLUGIN_SUCCESSFUL_FINISH); - - } - catch (AbortException | InterruptedException e) - { - listener.error("ABORTED"); - build.setResult(Result.ABORTED); - listener.error(Messages.PLUGIN_ERROR_FINISH); - } - catch (Exception e) - { - listener.error(Messages.PLUGIN_ERROR_FINISH); - listener.error(e.getMessage()); - listener.error(Messages.PLEASE_CONTACT_SUPPORT); - listener.error("FAILURE"); - build.setResult(Result.FAILURE); - } - - - return; - } - - - private static void CollectScheduleRunResults(String controllerApiHttpAddress, String accessKey, UUID runId, String scheduleName, int timeDelay,boolean isDoneStatusAsSuccess,boolean writePassedKeyframes, LeapworkRun resultRun, final TaskListener listener) throws AbortException, InterruptedException { - List runItemsId = new ArrayList<>(); - Object waiter = new Object(); - //get statuses - try(AsyncHttpClient client = new AsyncHttpClient()) - { - boolean isStillRunning = true; - - do - { - synchronized (waiter) - { - waiter.wait(timeDelay * 1000);//Time delay - } - - List executedRunItems = pluginHandler.getRunRunItems(client,controllerApiHttpAddress,accessKey,runId); - executedRunItems.removeAll(runItemsId); //left only new - - - for(ListIterator iter = executedRunItems.listIterator(); iter.hasNext();) - { - UUID runItemId = iter.next(); - RunItem runItem = pluginHandler.getRunItem(client,controllerApiHttpAddress,accessKey,runItemId, scheduleName,isDoneStatusAsSuccess,writePassedKeyframes,listener ); - - String status = runItem.getCaseStatus(); - - - resultRun.addTime(runItem.getElapsedTime()); - switch (status) - { - case "NoStatus": - case "Initializing": - case "Connecting": - case "Connected": - case "Running": - case "IsProcessing": - iter.remove(); - break; - case "Passed": - resultRun.incPassed(); - resultRun.runItems.add(runItem); - resultRun.incTotal(); - break; - case "Failed": - resultRun.incFailed(); - resultRun.runItems.add(runItem); - resultRun.incTotal(); - break; - case "Error": - case "Inconclusive": - case "Timeout": - case "Cancelled": - resultRun.incErrors(); - resultRun.runItems.add(runItem); - resultRun.incTotal(); - break; - case"Done": - resultRun.runItems.add(runItem); - if(isDoneStatusAsSuccess) - resultRun.incPassed(); - else - resultRun.incFailed(); - resultRun.incTotal(); - break; - - } - - } - - runItemsId.addAll(executedRunItems); - - String runStatus = pluginHandler.getRunStatus(client,controllerApiHttpAddress,accessKey,runId); - if(runStatus.contentEquals("Finished")) - { - List allExecutedRunItems = pluginHandler.getRunRunItems(client,controllerApiHttpAddress,accessKey,runId); - if(allExecutedRunItems.size() > 0 && allExecutedRunItems.size() <= runItemsId.size()) - isStillRunning = false; - } - - if(isStillRunning) - listener.getLogger().println(String.format("The schedule status is already '%1$s' - wait a minute...", runStatus)); - - } - while (isStillRunning); - - } - catch (AbortException | InterruptedException e) - { - Lock lock = new ReentrantLock(); - lock.lock(); - try - { - String interruptedExceptionMessage = String.format(Messages.INTERRUPTED_EXCEPTION, e.getMessage()); - listener.error(interruptedExceptionMessage); - RunItem invalidItem = new RunItem("Aborted run","Cancelled",0,e.getMessage(),scheduleName); - pluginHandler.stopRun(controllerApiHttpAddress,runId,scheduleName,accessKey, listener); - resultRun.incErrors(); - resultRun.runItems.add(invalidItem); - } - finally { - lock.unlock(); - throw e; - } - } - catch (Exception e) - { - listener.error(e.getMessage()); - RunItem invalidItem = new RunItem("Invalid run","Error",0,e.getMessage(),scheduleName); - resultRun.incErrors(); - resultRun.runItems.add(invalidItem); - } - } - - private void printPluginInputs(final TaskListener listener, String workspace) - { - listener.getLogger().println(Messages.INPUT_VALUES_MESSAGE); - listener.getLogger().println(Messages.CASE_CONSOLE_LOG_SEPARATOR); - listener.getLogger().println(String.format(Messages.INPUT_HOSTNAME_VALUE,getLeapworkHostname())); - listener.getLogger().println(String.format(Messages.INPUT_PORT_VALUE,getLeapworkPort())); - //listener.getLogger().println(String.format(Messages.INPUT_ACCESS_KEY_VALUE,getLeapworkAccessKey())); - listener.getLogger().println(String.format(Messages.INPUT_REPORT_VALUE,getLeapworkReport())); - listener.getLogger().println(String.format(Messages.INPUT_WORKSPACE_VALUE,workspace)); - listener.getLogger().println(String.format(Messages.INPUT_SCHEDULE_NAMES_VALUE,getLeapworkSchNames())); - listener.getLogger().println(String.format(Messages.INPUT_SCHEDULE_IDS_VALUE,getLeapworkSchIds())); - listener.getLogger().println(String.format(Messages.INPUT_DELAY_VALUE,getLeapworkDelay())); - listener.getLogger().println(String.format(Messages.INPUT_DONE_VALUE,getLeapworkDoneStatusAs())); - listener.getLogger().println(String.format(Messages.INPUT_WRITE_PASSED,isLeapworkWritePassedFlowKeyFrames())); - listener.getLogger().println(String.format(Messages.INPUT_VARIABLES,getLeapworkScheduleVariables())); - - } - - @Override - public DescriptorImpl getDescriptor() { - return (DescriptorImpl)super.getDescriptor(); - } - - - @Extension // This indicates to Jenkins that this is an implementation of an extension point. - public static final class DescriptorImpl extends BuildStepDescriptor { - - public DescriptorImpl() { load();} - - public ListBoxModel doFillLeapworkDoneStatusAsItems(@QueryParameter("leapworkDoneStatusAs") String selection) { - return new ListBoxModel( - new ListBoxModel.Option("Success", "Success",selection.matches("Success")), - new ListBoxModel.Option("Failed", "Failed",selection.matches("Failed")) - ); - } - - public boolean isApplicable(Class aClass) { - // Indicates that this builder can be used with all kinds of project types - return true; - } - - public static final String DEFAULT_DELAY = "5"; - public static final String DEFAULT_REPORT_NAME = "report.xml"; - public static final boolean DEFAULT_WRITE_PASSED_FLOW_KEYFRAMES = false; - - public FormValidation doCheckLeapworkDelay (@QueryParameter("leapworkDelay") String delay){ - int temp; - try { - temp = Integer.parseInt(delay); - - if ( temp < 1 ){ - return FormValidation.error("Entered number must be higher than 0"); - } - } catch (NumberFormatException ex){ - return FormValidation.error("Invalid number"); - } - return FormValidation.ok(); - } - public String getDefaultLeapworkDelay() { return DEFAULT_DELAY; } - public String getDefaultLeapworkReport() { return DEFAULT_REPORT_NAME; } - - public boolean getDefaultLeapworkWritePassedFlowKeyFrames() {return DEFAULT_WRITE_PASSED_FLOW_KEYFRAMES;} - - public String getDisplayName() { - return Messages.PLUGIN_NAME; - } - - @Override - public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { - save(); - return super.configure(req,formData); - } - - } - - - -} \ No newline at end of file +public class LeapworkJenkinsBridgeBuilder extends Builder implements SimpleBuildStep { + + private final String leapworkHostname; + private final String leapworkPort; + private final Secret leapworkAccessKey; + private String leapworkDelay; + private String leapworkDoneStatusAs; + private String leapworkReport; + private final String leapworkSchIds; + private final String leapworkSchNames; + private boolean leapworkWritePassedFlowKeyFrames; + private String leapworkScheduleVariables; + + private static PluginHandler pluginHandler = PluginHandler.getInstance(); + + // Fields in config.jelly must match the parameter names in the + // "DataBoundConstructor" + @DataBoundConstructor + public LeapworkJenkinsBridgeBuilder(String leapworkHostname, String leapworkPort, String leapworkAccessKey, + String leapworkDelay, String leapworkDoneStatusAs, String leapworkReport, String leapworkSchNames, + String leapworkSchIds/* , boolean leapworkWritePassedFlowKeyFrames */) { + + this.leapworkHostname = leapworkHostname; + this.leapworkPort = leapworkPort; + this.leapworkAccessKey = Secret.fromString(leapworkAccessKey); + this.leapworkDelay = leapworkDelay; + this.leapworkDoneStatusAs = leapworkDoneStatusAs; + this.leapworkReport = leapworkReport; + this.leapworkSchIds = leapworkSchIds; + this.leapworkSchNames = leapworkSchNames; + // this.leapworkWritePassedFlowKeyFrames = leapworkWritePassedFlowKeyFrames; + } + + @DataBoundSetter + public void setLeapworkReport(String report) { + this.leapworkReport = report; + } + + @DataBoundSetter + public void setLeapworkDoneStatusAs(String doneStatusAs) { + this.leapworkDoneStatusAs = doneStatusAs; + } + + @DataBoundSetter + public void setLeapworkDelay(String leapworkDelay) { + this.leapworkDelay = leapworkDelay; + } + + @DataBoundSetter + public void setLeapworkWritePassedFlowKeyFrames(boolean leapworkWritePassedFlowKeyFrames) { + this.leapworkWritePassedFlowKeyFrames = leapworkWritePassedFlowKeyFrames; + } + + @DataBoundSetter + public void setLeapworkScheduleVariables(String leapworkScheduleVariables) { + this.leapworkScheduleVariables = leapworkScheduleVariables; + } + + public String getLeapworkHostname() { + return leapworkHostname; + } + + public String getLeapworkPort() { + return leapworkPort; + } + + public Secret getLeapworkAccessKey() { + return leapworkAccessKey; + } + + public String getLeapworkDelay() { + return leapworkDelay; + } + + public String getLeapworkSchNames() { + return leapworkSchNames; + } + + public String getLeapworkSchIds() { + return leapworkSchIds; + } + + public String getLeapworkDoneStatusAs() { + return leapworkDoneStatusAs; + } + + public String getLeapworkReport() { + return leapworkReport; + } + + public boolean isLeapworkWritePassedFlowKeyFrames() { + return leapworkWritePassedFlowKeyFrames; + } + + public String getLeapworkScheduleVariables() { + return leapworkScheduleVariables; + } + + // @Override + public void perform(final Run build, FilePath workspace, Launcher launcher, final TaskListener listener) + throws IOException, InterruptedException { + + EnvVars env = build.getEnvironment(listener); + ArrayList invalidSchedules = new ArrayList<>(); + + String workspacePath = pluginHandler.getWorkSpaceSafe(workspace, env); + this.leapworkReport = pluginHandler.getReportFileName(this.getLeapworkReport(), + DescriptorImpl.DEFAULT_REPORT_NAME); + printPluginInputs(listener, workspacePath); + + ArrayList rawScheduleList = pluginHandler.getRawScheduleList(leapworkSchIds, leapworkSchNames); + String controllerApiHttpAddress = pluginHandler.getControllerApiHttpAdderess(leapworkHostname, leapworkPort, + listener); + + int timeDelay = pluginHandler.getTimeDelay(leapworkDelay, listener); + boolean isDoneStatusAsSuccess = pluginHandler.isDoneStatusAsSuccess(leapworkDoneStatusAs); + boolean writePassedKeyframes = isLeapworkWritePassedFlowKeyFrames(); + + String scheduleVariablesRequestPart = pluginHandler + .getScheduleVariablesRequestPart(getLeapworkScheduleVariables(), listener); + + try (AsyncHttpClient mainClient = new AsyncHttpClient()) { + + // Get schedule titles (or/and ids in case of pipeline) + LinkedHashMap schedulesIdTitleHashMap = pluginHandler.getSchedulesIdTitleHashMap(mainClient, + Secret.toString(leapworkAccessKey), controllerApiHttpAddress, rawScheduleList, listener, + invalidSchedules); + rawScheduleList.clear();// don't need that anymore + + if (schedulesIdTitleHashMap.isEmpty()) { + throw new Exception(Messages.NO_SCHEDULES); + } + + List schIdsList = new ArrayList<>(schedulesIdTitleHashMap.keySet()); + LinkedHashMap resultsMap = new LinkedHashMap<>(); + + ListIterator iter = schIdsList.listIterator(); + while (iter.hasNext()) { + + UUID schId = iter.next(); + String schTitle = schedulesIdTitleHashMap.get(schId); + LeapworkRun run = new LeapworkRun(schId.toString(), schTitle); + + UUID runId = pluginHandler.runSchedule(mainClient, controllerApiHttpAddress, Secret.toString(leapworkAccessKey), schId, + schTitle, listener, run, scheduleVariablesRequestPart); + if (runId != null) { + resultsMap.put(runId, run); + CollectScheduleRunResults(controllerApiHttpAddress, Secret.toString(leapworkAccessKey), runId, + schTitle, timeDelay, isDoneStatusAsSuccess, writePassedKeyframes, run, listener); + } else + resultsMap.put(UUID.randomUUID(), run); + + iter.remove(); + + } + + schIdsList.clear(); + schedulesIdTitleHashMap.clear(); + RunCollection buildResult = new RunCollection(); + + if (invalidSchedules.size() > 0) { + listener.getLogger().println(Messages.INVALID_SCHEDULES); + + for (InvalidSchedule invalidSchedule : invalidSchedules) { + listener.getLogger().println( + String.format("%1$s: %2$s", invalidSchedule.getName(), invalidSchedule.getStackTrace())); + LeapworkRun notFoundSchedule = new LeapworkRun(invalidSchedule.getName()); + RunItem invalidRunItem = new RunItem("Error", "Error", 0, invalidSchedule.getStackTrace(), + invalidSchedule.getName()); + notFoundSchedule.runItems.add(invalidRunItem); + notFoundSchedule.setError(invalidSchedule.getStackTrace()); + buildResult.leapworkRuns.add(notFoundSchedule); + } + + } + + List resultRuns = new ArrayList<>(resultsMap.values()); + listener.getLogger().println(Messages.TOTAL_SEPARATOR); + + for (LeapworkRun run : resultRuns) { + buildResult.leapworkRuns.add(run); + + buildResult.addFailedTests(run.getFailed()); + buildResult.addPassedTests(run.getPassed()); + buildResult.addErrors(run.getErrors()); + run.setTotal(run.getPassed() + run.getFailed()); + buildResult.addTotalTime(run.getTime()); + listener.getLogger() + .println(String.format(Messages.SCHEDULE_TITLE, run.getScheduleTitle(), run.getScheduleId())); + listener.getLogger().println(String.format(Messages.CASES_PASSED, run.getPassed())); + listener.getLogger().println(String.format(Messages.CASES_FAILED, run.getFailed())); + listener.getLogger().println(String.format(Messages.CASES_ERRORED, run.getErrors())); + } + buildResult.setTotalTests(buildResult.getFailedTests() + buildResult.getPassedTests()); + + listener.getLogger().println(Messages.TOTAL_SEPARATOR); + listener.getLogger().println(String.format(Messages.TOTAL_CASES_PASSED, buildResult.getPassedTests())); + listener.getLogger().println(String.format(Messages.TOTAL_CASES_FAILED, buildResult.getFailedTests())); + listener.getLogger().println(String.format(Messages.TOTAL_CASES_ERROR, buildResult.getErrors())); + + pluginHandler.createJUnitReport(workspace, leapworkReport, listener, buildResult); + + if (buildResult.getErrors() > 0 || buildResult.getFailedTests() > 0 || invalidSchedules.size() > 0) { + if (buildResult.getErrors() > 0) + listener.getLogger().println(Messages.ERROR_NOTIFICATION); + listener.getLogger().println("FAILURE"); + build.setResult(Result.FAILURE); + } else { + listener.getLogger().println("SUCCESS"); + build.setResult(Result.SUCCESS); + } + + listener.getLogger().println(Messages.PLUGIN_SUCCESSFUL_FINISH); + + } catch (AbortException | InterruptedException e) { + listener.error("ABORTED"); + build.setResult(Result.ABORTED); + listener.error(Messages.PLUGIN_ERROR_FINISH); + } catch (Exception e) { + listener.error(Messages.PLUGIN_ERROR_FINISH); + listener.error(e.getMessage()); + listener.error(Messages.PLEASE_CONTACT_SUPPORT); + listener.error("FAILURE"); + build.setResult(Result.FAILURE); + } + + return; + } + + private static void CollectScheduleRunResults(String controllerApiHttpAddress, String accessKey, UUID runId, + String scheduleName, int timeDelay, boolean isDoneStatusAsSuccess, boolean writePassedKeyframes, + LeapworkRun resultRun, final TaskListener listener) throws AbortException, InterruptedException { + List runItemsId = new ArrayList<>(); + Object waiter = new Object(); + // get statuses + try (AsyncHttpClient client = new AsyncHttpClient()) { + boolean isStillRunning = true; + + do { + synchronized (waiter) { + waiter.wait(timeDelay * 1000);// Time delay + } + + List executedRunItems = pluginHandler.getRunRunItems(client, controllerApiHttpAddress, accessKey, + runId); + executedRunItems.removeAll(runItemsId); // left only new + + for (ListIterator iter = executedRunItems.listIterator(); iter.hasNext();) { + UUID runItemId = iter.next(); + RunItem runItem = pluginHandler.getRunItem(client, controllerApiHttpAddress, accessKey, runItemId, + scheduleName, isDoneStatusAsSuccess, writePassedKeyframes, listener); + + String status = runItem.getCaseStatus(); + + resultRun.addTime(runItem.getElapsedTime()); + switch (status) { + case "NoStatus": + case "Initializing": + case "Connecting": + case "Connected": + case "Running": + case "IsProcessing": + iter.remove(); + break; + case "Passed": + resultRun.incPassed(); + resultRun.runItems.add(runItem); + resultRun.incTotal(); + break; + case "Failed": + resultRun.incFailed(); + resultRun.runItems.add(runItem); + resultRun.incTotal(); + break; + case "Error": + case "Inconclusive": + case "Timeout": + case "Cancelled": + resultRun.incErrors(); + resultRun.runItems.add(runItem); + resultRun.incTotal(); + break; + case "Done": + resultRun.runItems.add(runItem); + if (isDoneStatusAsSuccess) + resultRun.incPassed(); + else + resultRun.incFailed(); + resultRun.incTotal(); + break; + + } + + } + + runItemsId.addAll(executedRunItems); + + String runStatus = pluginHandler.getRunStatus(client, controllerApiHttpAddress, accessKey, runId); + if (runStatus.contentEquals("Finished")) { + List allExecutedRunItems = pluginHandler.getRunRunItems(client, controllerApiHttpAddress, + accessKey, runId); + if (allExecutedRunItems.size() > 0 && allExecutedRunItems.size() <= runItemsId.size()) + isStillRunning = false; + } + + if (isStillRunning) + listener.getLogger().println( + String.format("The schedule status is already '%1$s' - wait a minute...", runStatus)); + + } while (isStillRunning); + + } catch (AbortException | InterruptedException e) { + Lock lock = new ReentrantLock(); + lock.lock(); + try { + String interruptedExceptionMessage = String.format(Messages.INTERRUPTED_EXCEPTION, e.getMessage()); + listener.error(interruptedExceptionMessage); + RunItem invalidItem = new RunItem("Aborted run", "Cancelled", 0, e.getMessage(), scheduleName); + pluginHandler.stopRun(controllerApiHttpAddress, runId, scheduleName, accessKey, listener); + resultRun.incErrors(); + resultRun.runItems.add(invalidItem); + } finally { + lock.unlock(); + throw e; + } + } catch (Exception e) { + listener.error(e.getMessage()); + RunItem invalidItem = new RunItem("Invalid run", "Error", 0, e.getMessage(), scheduleName); + resultRun.incErrors(); + resultRun.runItems.add(invalidItem); + } + } + + private void printPluginInputs(final TaskListener listener, String workspace) { + listener.getLogger().println(Messages.INPUT_VALUES_MESSAGE); + listener.getLogger().println(Messages.CASE_CONSOLE_LOG_SEPARATOR); + listener.getLogger().println(String.format(Messages.INPUT_HOSTNAME_VALUE, getLeapworkHostname())); + listener.getLogger().println(String.format(Messages.INPUT_PORT_VALUE, getLeapworkPort())); + // listener.getLogger().println(String.format(Messages.INPUT_ACCESS_KEY_VALUE,getLeapworkAccessKey())); + listener.getLogger().println(String.format(Messages.INPUT_REPORT_VALUE, getLeapworkReport())); + listener.getLogger().println(String.format(Messages.INPUT_WORKSPACE_VALUE, workspace)); + listener.getLogger().println(String.format(Messages.INPUT_SCHEDULE_NAMES_VALUE, getLeapworkSchNames())); + listener.getLogger().println(String.format(Messages.INPUT_SCHEDULE_IDS_VALUE, getLeapworkSchIds())); + listener.getLogger().println(String.format(Messages.INPUT_DELAY_VALUE, getLeapworkDelay())); + listener.getLogger().println(String.format(Messages.INPUT_DONE_VALUE, getLeapworkDoneStatusAs())); + listener.getLogger().println(String.format(Messages.INPUT_WRITE_PASSED, isLeapworkWritePassedFlowKeyFrames())); + listener.getLogger().println(String.format(Messages.INPUT_VARIABLES, getLeapworkScheduleVariables())); + + } + + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + + @Extension // This indicates to Jenkins that this is an implementation of an extension + // point. + public static final class DescriptorImpl extends BuildStepDescriptor { + + public DescriptorImpl() { + load(); + } + + public ListBoxModel doFillLeapworkDoneStatusAsItems(@QueryParameter("leapworkDoneStatusAs") String selection) { + return new ListBoxModel(new ListBoxModel.Option("Success", "Success", selection.matches("Success")), + new ListBoxModel.Option("Failed", "Failed", selection.matches("Failed"))); + } + + public boolean isApplicable(Class aClass) { + // Indicates that this builder can be used with all kinds of project types + return true; + } + + public static final String DEFAULT_DELAY = "5"; + public static final String DEFAULT_REPORT_NAME = "report.xml"; + public static final boolean DEFAULT_WRITE_PASSED_FLOW_KEYFRAMES = false; + + public FormValidation doCheckLeapworkDelay(@QueryParameter("leapworkDelay") String delay) { + int temp; + try { + temp = Integer.parseInt(delay); + + if (temp < 1) { + return FormValidation.error("Entered number must be higher than 0"); + } + } catch (NumberFormatException ex) { + return FormValidation.error("Invalid number"); + } + return FormValidation.ok(); + } + + public String getDefaultLeapworkDelay() { + return DEFAULT_DELAY; + } + + public String getDefaultLeapworkReport() { + return DEFAULT_REPORT_NAME; + } + + public boolean getDefaultLeapworkWritePassedFlowKeyFrames() { + return DEFAULT_WRITE_PASSED_FLOW_KEYFRAMES; + } + + public String getDisplayName() { + return Messages.PLUGIN_NAME; + } + + @Override + public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { + save(); + return super.configure(req, formData); + } + + } + +} \ No newline at end of file From 1307a8259da67926c4dfe7ea84c7ae416023ceab Mon Sep 17 00:00:00 2001 From: Bir Sikander Date: Wed, 28 Jul 2021 21:05:22 +0530 Subject: [PATCH 2/2] updating source with hudson.util.secret library --- target/Leapwork.hpi | Bin 3784147 -> 3784197 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/target/Leapwork.hpi b/target/Leapwork.hpi index ca30482ae50ea4534bc93440e66d3bb21e26395b..97f813640da2be79d5f99afbcd0c6ac8b77970a5 100644 GIT binary patch delta 24767 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 delta 24700 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 byS)JUf5uWa{I{+E?6d=d{c5k_U-th1@RcV@