From 5230cf7132b1ffbea074d662f254eb577b103eb6 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Wed, 29 Mar 2023 15:25:05 -0700 Subject: [PATCH] fix: should fix datafile compress issue in QA + adding new routes for clients fix: unneeded file feat: adding new names routes and updating swagger ui routes + err msgs fix: small doc/import changes + trigger QA build fix: updating error descriptions + adding missing service call fix: small doc change --- .../mvc/rest/controllers/AgentController.java | 73 +++++++++++-------- .../rest/controllers/DataFileController.java | 10 +++ .../mvc/rest/controllers/JobController.java | 68 ++++++++--------- .../rest/controllers/ProjectController.java | 35 +++++++++ .../rest/controllers/ScriptController.java | 10 +++ .../errors/GenericExceptionHandler.java | 2 +- .../rest/models/jobs/CreateJobRequest.java | 1 - .../rest/services/agent/AgentServiceV2.java | 26 ++++++- .../services/agent/AgentServiceV2Impl.java | 26 ++++++- .../services/datafiles/DataFileServiceV2.java | 9 +++ .../datafiles/DataFileServiceV2Impl.java | 32 +++++--- .../mvc/rest/services/jobs/JobServiceV2.java | 20 +++-- .../rest/services/jobs/JobServiceV2Impl.java | 23 +++--- .../services/projects/ProjectServiceV2.java | 23 ++++++ .../projects/ProjectServiceV2Impl.java | 36 +++++++++ .../services/scripts/ScriptServiceV2.java | 9 +++ .../services/scripts/ScriptServiceV2Impl.java | 11 +++ .../rest/controllers/AgentControllerTest.java | 35 +++++++-- .../controllers/DataFileControllerTest.java | 11 +++ .../rest/controllers/JobControllerTest.java | 30 +++++--- .../controllers/ProjectControllerTest.java | 43 ++++++++++- .../controllers/ScriptControllerTest.java | 11 +++ 22 files changed, 426 insertions(+), 118 deletions(-) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/AgentController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/AgentController.java index e1095e51b..e89b125b8 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/AgentController.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/AgentController.java @@ -11,8 +11,9 @@ import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.rest.mvc.rest.services.agent.AgentServiceV2; import com.intuit.tank.vm.agent.messages.Headers; -import com.intuit.tank.vm.agent.messages.AgentTestStartData; +import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentData; +import com.intuit.tank.vm.agent.messages.AgentTestStartData; import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpStatus; @@ -80,10 +81,10 @@ public ResponseEntity getSupportFiles() th } @RequestMapping(value = "/ready", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE }) - @Operation(description = "Registers an agent instance to a job and sets it's status to ready to start", summary = "Set an agent instance status to ready to start") + @Operation(description = "Registers an agent instance to a job and sets it's status to ready to start", summary = "Set an agent instance status to ready to start", hidden = true) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Successfully set agent to ready"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "400", description = "Could not register agent due to bad request", content = @Content) }) public ResponseEntity agentReady( @RequestBody @Parameter(description = "agentData object that contains agent data settings", required = true) AgentData agentData) { @@ -110,6 +111,18 @@ public ResponseEntity getClients() { return new ResponseEntity<>(agentService.getClients(), HttpStatus.OK); } + @RequestMapping(value = "/availability", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE }) + @Operation(description = "Sets the availability status for a standalone agent", summary = "Set standalone agent availability", hidden = true) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully set agent availability"), + @ApiResponse(responseCode = "400", description = "Could not update agent availability due to bad request", content = @Content) + }) + public ResponseEntity setStandaloneAgentAvailability( + @RequestBody @Parameter(description = "Agent availability request to update standalone agent availability", required = true) AgentAvailability availability) { + agentService.setStandaloneAgentAvailability(availability); + return ResponseEntity.ok().build(); + } + // Instance status operations @RequestMapping(value = "/instance/status/{instanceId}", method = RequestMethod.GET) @Operation(description = "Returns the agent instance status", summary = "Get the agent instance status") @@ -122,14 +135,14 @@ public ResponseEntity getInstanceStatus(@PathVariable @Parameter( if (status != null) { return new ResponseEntity(status, HttpStatus.OK); } - return new ResponseEntity(status, HttpStatus.NOT_FOUND); + return ResponseEntity.notFound().build(); } @RequestMapping(value = "/instance/status/{instanceId}", method = RequestMethod.PUT, consumes = { MediaType.APPLICATION_JSON_VALUE }) - @Operation(description = "Sets the agent instance status via instanceID and CloudVMStatus payload", summary = "Set the agent instance status") + @Operation(description = "Sets the agent instance status via instanceID and CloudVMStatus payload", summary = "Set the agent instance status", hidden = true) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Successfully set agent instance status"), - @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content) + @ApiResponse(responseCode = "400", description = "Could not update agent instance status due to bad request", content = @Content) }) public ResponseEntity setInstanceStatus(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId, @RequestBody @Parameter(description = "CloudVmStatus object that contains updated content", required = true) CloudVmStatus status) { @@ -137,47 +150,47 @@ public ResponseEntity setInstanceStatus(@PathVariable @Parameter(descripti return ResponseEntity.ok().build(); } - @RequestMapping(value = "/instance/stop/{instanceId}", method = RequestMethod.GET) + @RequestMapping(value = "/instance/stop/{instanceId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Stops specific agent instance by instance ID", summary = "Stop an agent instance") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully stopped agent instance"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully stopped agent instance"), + @ApiResponse(responseCode = "400", description = "Could not update agent instance status due to invalid instanceId", content = @Content) }) - public ResponseEntity stopInstance(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId) { - agentService.stopInstance(instanceId); - return ResponseEntity.noContent().build(); + public ResponseEntity stopInstance(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId) { + String status = agentService.stopInstance(instanceId); + return new ResponseEntity<>(status, HttpStatus.OK); } - @RequestMapping(value = "/instance/pause/{instanceId}", method = RequestMethod.GET) + @RequestMapping(value = "/instance/pause/{instanceId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Pauses a specific running agent instance by instance ID", summary = "Pause a running agent instance") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully paused agent instance"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully paused agent instance"), + @ApiResponse(responseCode = "400", description = "Could not update agent instance status due to invalid instanceId", content = @Content) }) - public ResponseEntity pauseInstance(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId) { - agentService.pauseInstance(instanceId); - return ResponseEntity.noContent().build(); + public ResponseEntity pauseInstance(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId) { + String status = agentService.pauseInstance(instanceId); + return new ResponseEntity<>(status, HttpStatus.OK); } - @RequestMapping(value = "/instance/resume/{instanceId}", method = RequestMethod.GET) + @RequestMapping(value = "/instance/resume/{instanceId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Resumes a specific paused agent instance by instance ID", summary = "Resume a paused agent instance") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully resumed agent instance"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully resumed agent instance"), + @ApiResponse(responseCode = "400", description = "Could not update agent instance status due to invalid instanceId", content = @Content) }) - public ResponseEntity resumeInstance(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId) { - agentService.resumeInstance(instanceId); - return ResponseEntity.noContent().build(); + public ResponseEntity resumeInstance(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId) { + String status = agentService.resumeInstance(instanceId); + return new ResponseEntity<>(status, HttpStatus.OK); } - @RequestMapping(value = "/instance/kill/{instanceId}", method = RequestMethod.GET) + @RequestMapping(value = "/instance/kill/{instanceId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Terminates a specific agent instance by instance ID", summary = "Terminate an agent instance") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully terminated agent instance"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully terminated agent instance"), + @ApiResponse(responseCode = "400", description = "Could not update agent instance status due to invalid instanceId", content = @Content) }) - public ResponseEntity killInstance(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId) { - agentService.killInstance(instanceId); - return ResponseEntity.noContent().build(); + public ResponseEntity killInstance(@PathVariable @Parameter(description = "The instance ID associated with the instance", required = true) String instanceId) { + String status = agentService.killInstance(instanceId); + return new ResponseEntity<>(status, HttpStatus.OK); } } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileController.java index ebe0ef441..a72200b66 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileController.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileController.java @@ -59,6 +59,16 @@ public ResponseEntity getDatafiles() { return new ResponseEntity<>(dataFileService.getDatafiles(), HttpStatus.OK); } + @RequestMapping(value = "/names", method = RequestMethod.GET) + @Operation(description = "Returns all datafile names with corresponding datafile IDs", summary = "Get all datafile names with datafile IDs") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully found all datafile names with IDs", content = @Content), + @ApiResponse(responseCode = "404", description = "All datafile names with IDs could not be found", content = @Content) + }) + public ResponseEntity> getAllDatafileNames() { + return new ResponseEntity<>(dataFileService.getAllDatafileNames(), HttpStatus.OK); + } + @RequestMapping(value = "/{datafileId}", method = RequestMethod.GET) @Operation(description = "Returns a specific datafile description by datafile ID", summary = "Get a specific datafile description") @ApiResponses(value = { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java index 29bf5023c..5bf0541d2 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java @@ -80,9 +80,11 @@ public ResponseEntity getJobsByProject(@PathVariable @Parameter(de @RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE }) @Operation(description = "Given a job request payload, creates a new job under an existing project and returns new jobId and created status in response \n\n" + - "Note: Make sure projectId matches an existing project to successfully add job to project's job queue" + + "Note: Make sure projectId matches an existing project to successfully create the job for that project \n\n" + "Parameters: \n\n" + - " - jobInstanceName is accepted as a string \n\n" + + " - jobInstanceName and projectName are accepted as strings (both optional) \n\n" + + " - jobInstanceName overrides projectName for naming jobs \n\n" + + " - passing only projectName creates jobs named: '{projectName}_{total_users}\\_users\\_{timestamp}' \n\n" + " - rampTime and simulationTime are accepted as time strings i.e 60s, 12m, 24h \n\n" + " - stopBehavior is matched against accepted values ( END_OF_STEP, END_OF_SCRIPT, END_OF_SCRIPT_GROUP, END_OF_TEST ) \n\n" + " - vmInstance matches against AWS EC2 Instance Types i.e c5.large, c5.xlarge, etc \n\n"+ @@ -91,7 +93,7 @@ public ResponseEntity getJobsByProject(@PathVariable @Parameter(de " - jobRegions.users are accepted as integer strings i.e \"100\", \"4000\" \n\n", summary = "Create a new job") @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "Successfully created job", content = @Content), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "400", description = "Could not create job due to bad request", content = @Content) }) public ResponseEntity> createJob( @RequestBody @Parameter(description = "request", required = true) CreateJobRequest request) { @@ -146,58 +148,58 @@ public ResponseEntity getJobVMStatuses(@PathVariable @Pa // Job Status Setters - @RequestMapping(value = "/start/{jobId}", method = RequestMethod.GET) + @RequestMapping(value = "/start/{jobId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Starts a specific job by job id", summary = "Start a specific job") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully started job"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully started job"), + @ApiResponse(responseCode = "400", description = "Could not update job status due to invalid jobId", content = @Content) }) - public ResponseEntity startJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { - jobService.startJob(jobId); - return ResponseEntity.noContent().build(); + public ResponseEntity startJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { + String status = jobService.startJob(jobId); + return new ResponseEntity<>(status, HttpStatus.OK); } - @RequestMapping(value = "/stop/{jobId}", method = RequestMethod.GET) + @RequestMapping(value = "/stop/{jobId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Stops a specific job by job id", summary = "Stop a specific job") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully stopped job"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully stopped job"), + @ApiResponse(responseCode = "400", description = "Could not update job status due to invalid jobId", content = @Content) }) - public ResponseEntity stopJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { - jobService.stopJob(jobId); - return ResponseEntity.noContent().build(); + public ResponseEntity stopJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { + String status = jobService.stopJob(jobId); + return new ResponseEntity<>(status, HttpStatus.OK); } - @RequestMapping(value = "/pause/{jobId}", method = RequestMethod.GET) + @RequestMapping(value = "/pause/{jobId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Pauses a specific job by job id", summary = "Pause a job") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully paused job"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully paused job"), + @ApiResponse(responseCode = "400", description = "Could not update job status due to invalid jobId", content = @Content) }) - public ResponseEntity pauseJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { - jobService.pauseJob(jobId); - return ResponseEntity.noContent().build(); + public ResponseEntity pauseJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { + String status = jobService.pauseJob(jobId); + return new ResponseEntity<>(status, HttpStatus.OK); } - @RequestMapping(value = "/resume/{jobId}", method = RequestMethod.GET) + @RequestMapping(value = "/resume/{jobId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Resumes a specific job by job id", summary = "Resume a paused job") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully resumed job"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully resumed job"), + @ApiResponse(responseCode = "400", description = "Could not update job status due to invalid jobId", content = @Content) }) - public ResponseEntity resumeJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { - jobService.resumeJob(jobId); - return ResponseEntity.noContent().build(); + public ResponseEntity resumeJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { + String status = jobService.resumeJob(jobId); + return new ResponseEntity<>(status, HttpStatus.OK); } - @RequestMapping(value = "/kill/{jobId}", method = RequestMethod.GET) + @RequestMapping(value = "/kill/{jobId}", method = RequestMethod.GET, produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Terminates a specific job by job id", summary = "Terminate a specific job") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Successfully terminated job"), - @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully terminated job"), + @ApiResponse(responseCode = "400", description = "Could not update job status due to invalid jobId", content = @Content) }) - public ResponseEntity killJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { - jobService.killJob(jobId); - return ResponseEntity.noContent().build(); + public ResponseEntity killJob(@PathVariable @Parameter(description = "The job ID associated with the job", required = true) Integer jobId) { + String status = jobService.killJob(jobId); + return new ResponseEntity<>(status, HttpStatus.OK); } } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ProjectController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ProjectController.java index f04c8b8a1..63e37189e 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ProjectController.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ProjectController.java @@ -23,9 +23,11 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import javax.annotation.Resource; +import java.io.IOException; import java.net.URI; import java.util.Map; import java.util.Objects; @@ -57,6 +59,16 @@ public ResponseEntity getAllProjects() { return new ResponseEntity<>(projectService.getAllProjects(), HttpStatus.OK); } + @RequestMapping(value = "/names", method = RequestMethod.GET) + @Operation(description = "Returns all project names with corresponding project IDs", summary = "Get all project names with project IDs") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully found all project names with IDs", content = @Content), + @ApiResponse(responseCode = "404", description = "All project names with IDs could not be found", content = @Content) + }) + public ResponseEntity> getAllProjectNames() { + return new ResponseEntity<>(projectService.getAllProjectNames(), HttpStatus.OK); + } + @RequestMapping(value = "/{projectId}", method = RequestMethod.GET) @Operation(description = "Gets a specific project description by project ID", summary = "Get a specific project description") @ApiResponses(value = { @@ -113,6 +125,29 @@ public ResponseEntity> updateProject( return new ResponseEntity<>(response, HttpStatus.OK); } + @RequestMapping(value = "/download/{projectId}", method = RequestMethod.GET) + @Operation(description = "Downloads a project's harness XML file", summary = "Download the project's harness file") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully downloaded project's harness file", content = @Content), + @ApiResponse(responseCode = "404", description = "Project's harness file could not be found", content = @Content) + }) + public ResponseEntity downloadTestScriptForProject(@PathVariable @Parameter(description = "Project ID", required = true) Integer projectId) throws IOException { + Map response = projectService.downloadTestScriptForProject(projectId); + if (response == null) { + return ResponseEntity.notFound().build(); + } + String filename = response.keySet().iterator().next(); + StreamingResponseBody responseBody = response.get(filename); + + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\""); + + return ResponseEntity.ok() + .headers(headers) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(responseBody); + } + @RequestMapping(value = "/{projectId}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) @ResponseStatus(HttpStatus.NO_CONTENT) @Operation(description = "Deletes a specific project by project ID", summary = "Delete a project") diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptController.java index 1ef41cf07..8a270b7f8 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptController.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptController.java @@ -63,6 +63,16 @@ public ResponseEntity getScripts() { return new ResponseEntity<>(scriptService.getScripts(), HttpStatus.OK); } + @RequestMapping(value = "/names", method = RequestMethod.GET) + @Operation(description = "Returns all script names with corresponding script IDs", summary = "Get all script names with script IDs") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully found all script names with IDs", content = @Content), + @ApiResponse(responseCode = "404", description = "All script names with IDs could not be found", content = @Content) + }) + public ResponseEntity> getAllScriptNames() { + return new ResponseEntity<>(scriptService.getAllScriptNames(), HttpStatus.OK); + } + @RequestMapping(value = "/{scriptId}", method = RequestMethod.GET) @Operation(description = "Returns a specific script description by script ID", summary = "Get a specific script description") @ApiResponses(value = { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericExceptionHandler.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericExceptionHandler.java index e9f07c6cb..530a4a486 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericExceptionHandler.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericExceptionHandler.java @@ -71,7 +71,7 @@ public SimpleErrorResponse handleOtherErrors(Throwable t) { } private SimpleErrorResponse genericErrorResponse(HttpStatus status, String message, Throwable e) { - final boolean scrubSensitiveData = !includeDebugInfo; // API-1890: be very explicit about the flipping of the sense of the flag + final boolean scrubSensitiveData = !includeDebugInfo; return new SimpleErrorResponse(status, message, e, scrubSensitiveData); } } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/jobs/CreateJobRequest.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/jobs/CreateJobRequest.java index cec0e5883..350494078 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/jobs/CreateJobRequest.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/jobs/CreateJobRequest.java @@ -23,7 +23,6 @@ public class CreateJobRequest implements Serializable { private static final long serialVersionUID = 1L; - @JsonProperty(access = JsonProperty.Access.READ_ONLY) @XmlElement(name="projectName") private String projectName; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/agent/AgentServiceV2.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/agent/AgentServiceV2.java index d7fbd742d..a874e9011 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/agent/AgentServiceV2.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/agent/AgentServiceV2.java @@ -12,6 +12,7 @@ import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; import com.intuit.tank.vm.agent.messages.Headers; +import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentTestStartData; import com.intuit.tank.vm.agent.messages.AgentData; @@ -80,6 +81,15 @@ public interface AgentServiceV2 { */ public TankHttpClientDefinitionContainer getClients(); + /** + * Sets the availability status for a standalone agent + * + * @throws GenericServiceCreateOrUpdateException + * if there is an error setting standalone agent availability + */ + public void setStandaloneAgentAvailability(AgentAvailability availability); + + // Instance status operations /** @@ -112,8 +122,10 @@ public interface AgentServiceV2 { * * @throws GenericServiceCreateOrUpdateException * if there is an error stopping instance + * + * @return instance status */ - public void stopInstance(String instanceId); + public String stopInstance(String instanceId); /** * Pauses a running instance based on the provided instanceId @@ -122,8 +134,10 @@ public interface AgentServiceV2 { * * @throws GenericServiceCreateOrUpdateException * if there is an error pausing instance + * + * @return instance status */ - public void pauseInstance(String instanceId); + public String pauseInstance(String instanceId); /** * Resumes a paused instance based on the provided instanceId @@ -132,8 +146,10 @@ public interface AgentServiceV2 { * * @throws GenericServiceCreateOrUpdateException * if there is an error resuming instance + * + * @return instance status */ - public void resumeInstance(String instanceId); + public String resumeInstance(String instanceId); /** * Kills an instance based on the provided instanceId @@ -142,7 +158,9 @@ public interface AgentServiceV2 { * * @throws GenericServiceCreateOrUpdateException * if there is an error terminating instance + * + * @return instance status */ - public void killInstance(String instanceId); + public String killInstance(String instanceId); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/agent/AgentServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/agent/AgentServiceV2Impl.java index 58b3df848..5f60c6fe4 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/agent/AgentServiceV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/agent/AgentServiceV2Impl.java @@ -23,8 +23,10 @@ import com.intuit.tank.vm.settings.TankConfig; import com.intuit.tank.vm.agent.messages.Header; import com.intuit.tank.vm.agent.messages.Headers; +import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentTestStartData; import com.intuit.tank.vm.agent.messages.AgentData; +import com.intuit.tank.vm.perfManager.StandaloneAgentTracker; import com.amazonaws.xray.AWSXRay; import com.amazonaws.xray.entities.Segment; @@ -184,6 +186,18 @@ public TankHttpClientDefinitionContainer getClients() { } } + @Override + public void setStandaloneAgentAvailability(AgentAvailability availability) { + try { + StandaloneAgentTracker tracker = new ServletInjector().getManagedBean(servletContext, StandaloneAgentTracker.class); + LOGGER.info("Adding agent availability: " + availability); + tracker.addAvailability(availability); + } catch (Exception e) { + LOGGER.error("Error setting agent availability: " + e.getMessage(), e); + throw new GenericServiceCreateOrUpdateException("agent", "agent availability", e); + } + } + @Override public CloudVmStatus getInstanceStatus(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); @@ -216,12 +230,13 @@ public void setInstanceStatus(String instanceId, CloudVmStatus status) { } @Override - public void stopInstance(String instanceId) { + public String stopInstance(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { JobController controller = new ServletInjector().getManagedBean( servletContext, JobController.class); controller.stopAgent(instanceId); + return getInstanceStatus(instanceId).getVmStatus().name(); } catch (Exception e) { LOGGER.error("Error stopping instance: " + e.getMessage(), e); throw new GenericServiceCreateOrUpdateException("agent", "instance status to stop", e); @@ -229,12 +244,13 @@ public void stopInstance(String instanceId) { } @Override - public void pauseInstance(String instanceId) { + public String pauseInstance(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { JobController controller = new ServletInjector().getManagedBean( servletContext, JobController.class); controller.pauseRampInstance(instanceId); + return getInstanceStatus(instanceId).getVmStatus().name(); } catch (Exception e) { LOGGER.error("Error pausing running instance: " + e.getMessage(), e); throw new GenericServiceCreateOrUpdateException("agent", "instance status to pause", e); @@ -242,12 +258,13 @@ public void pauseInstance(String instanceId) { } @Override - public void resumeInstance(String instanceId) { + public String resumeInstance(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { JobController controller = new ServletInjector().getManagedBean( servletContext, JobController.class); controller.resumeRampInstance(instanceId); + return getInstanceStatus(instanceId).getVmStatus().name(); } catch (Exception e) { LOGGER.error("Error resuming instance: " + e.getMessage(), e); throw new GenericServiceCreateOrUpdateException("agent", "instance status to resume", e); @@ -255,12 +272,13 @@ public void resumeInstance(String instanceId) { } @Override - public void killInstance(String instanceId) { + public String killInstance(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { JobController controller = new ServletInjector().getManagedBean( servletContext, JobController.class); controller.killInstance(instanceId); + return getInstanceStatus(instanceId).getVmStatus().name(); } catch (Exception e) { LOGGER.error("Error killing instance: " + e.getMessage(), e); throw new GenericServiceCreateOrUpdateException("agent", "instance status to terminate", e); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/datafiles/DataFileServiceV2.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/datafiles/DataFileServiceV2.java index 1e4f2d303..40a25f6c6 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/datafiles/DataFileServiceV2.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/datafiles/DataFileServiceV2.java @@ -75,6 +75,15 @@ public interface DataFileServiceV2 { */ public DataFileDescriptorContainer getDatafiles(); + /** + * Gets all datafile names along with datafileId + * + * @throws GenericServiceResourceNotFoundException + * if there is an error returning all datafile names + * + * @return map of datafile < datafileName, datafileId > JSON response + */ + public Map getAllDatafileNames(); /** * Upload datafile to Tank diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/datafiles/DataFileServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/datafiles/DataFileServiceV2Impl.java index eacd79b83..9004212bc 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/datafiles/DataFileServiceV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/datafiles/DataFileServiceV2Impl.java @@ -24,6 +24,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.commons.io.IOUtils; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; @@ -75,6 +76,17 @@ public DataFileDescriptorContainer getDatafiles() { } } + @Override + public Map getAllDatafileNames(){ + try { + List all = new DataFileDao().findAll(); + return all.stream().collect(Collectors.toMap(DataFile::getId, DataFile::getPath)); + } catch (Exception e) { + LOGGER.error("Error returning all datafile names: " + e.getMessage(), e); + throw new GenericServiceResourceNotFoundException("datafiles", "all datafile names", e); + } + } + @Override public StreamingResponseBody getDatafileContent(Integer datafileId, Integer offset, Integer numLines){ DataFileDao dataFileDao = new DataFileDao(); @@ -139,13 +151,13 @@ public Map uploadDatafile(Integer datafileId, String contentEnco Map payload = new HashMap<>(); datafileId = datafileId == null ? 0 : datafileId; contentEncoding = contentEncoding == null ? "" : contentEncoding; - InputStream decompressed = StringUtils.equalsIgnoreCase(contentEncoding, "gzip") ? - new GZIPInputStream(file.getInputStream()) : - file.getInputStream(); - try { + BufferedReader bufferedReader = StringUtils.equalsIgnoreCase(contentEncoding, "gzip") ? + new BufferedReader(new InputStreamReader(new GZIPInputStream(file.getInputStream()))) : + new BufferedReader(new InputStreamReader(file.getInputStream())); + try (InputStream decompressed = IOUtils.toInputStream(IOUtils.toString(bufferedReader), StandardCharsets.UTF_8)) { DataFileDao dao = new DataFileDao(); DataFile dataFile = dao.findById(datafileId); - if (dataFile == null){ + if (dataFile == null) { dataFile = new DataFile(); dataFile.setCreator("System"); dataFile.setId(0); @@ -167,13 +179,15 @@ public Map uploadDatafile(Integer datafileId, String contentEnco } } payload.put("datafileId", Integer.toString(dataFile.getId())); + try { + decompressed.close(); + } catch (IOException e) { + LOGGER.error("Error uploading datafile: " + e.getMessage(), e); + throw new GenericServiceCreateOrUpdateException("datafiles", "new datafile via datafile upload", e); + } } catch (Exception e) { LOGGER.error("Error uploading datafile: " + e.getMessage(), e); throw new GenericServiceCreateOrUpdateException("datafiles", "new datafile via datafile upload", e); - } finally { - try { - decompressed.close(); - } catch (IOException e) {} } return payload; } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/jobs/JobServiceV2.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/jobs/JobServiceV2.java index e2e2bb6a1..3b98205d4 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/jobs/JobServiceV2.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/jobs/JobServiceV2.java @@ -114,8 +114,10 @@ public interface JobServiceV2 { * if there is an error starting the job * * @param jobId jobId for job + * + * @return job status */ - public void startJob(Integer jobId); + public String startJob(Integer jobId); /** * Stops a job based on the provided jobId @@ -124,8 +126,10 @@ public interface JobServiceV2 { * if there is an error stopping the job * * @param jobId jobId for job + * + * @return job status */ - public void stopJob(Integer jobId); + public String stopJob(Integer jobId); /** * Pauses a running job based on the provided jobId @@ -134,8 +138,10 @@ public interface JobServiceV2 { * if there is an error pausing the job * * @param jobId jobId for job + * + * @return job status */ - public void pauseJob(Integer jobId); + public String pauseJob(Integer jobId); /** @@ -145,8 +151,10 @@ public interface JobServiceV2 { * if there is an error resuming the job * * @param jobId jobId for job + * + * @return job status */ - public void resumeJob(Integer jobId); + public String resumeJob(Integer jobId); /** * Kills a job based on the provided jobId @@ -155,6 +163,8 @@ public interface JobServiceV2 { * if there is an error terminating the job * * @param jobId jobId for job + * + * @return job status */ - public void killJob(Integer jobId); + public String killJob(Integer jobId); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/jobs/JobServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/jobs/JobServiceV2Impl.java index 576e14d7c..0486997be 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/jobs/JobServiceV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/jobs/JobServiceV2Impl.java @@ -7,7 +7,6 @@ */ package com.intuit.tank.rest.mvc.rest.services.jobs; -import com.intuit.tank.api.cloud.VMTracker; import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; import com.intuit.tank.dao.BaseDao; import com.intuit.tank.dao.DataFileDao; @@ -198,12 +197,13 @@ public List> getAllJobStatus(){ // Job Status Setters @Override - public void startJob(Integer jobId) { + public String startJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { JobController controller = new ServletInjector().getManagedBean(servletContext, JobController.class); controller.startJob(Integer.toString(jobId)); + return getJobStatus(jobId); } catch (Exception e) { LOGGER.error("Error starting job: " + e); throw new GenericServiceCreateOrUpdateException("jobs", "job status to start", e); @@ -211,12 +211,13 @@ public void startJob(Integer jobId) { } @Override - public void stopJob(Integer jobId) { + public String stopJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { JobController controller = new ServletInjector().getManagedBean(servletContext, JobController.class); controller.stopJob(Integer.toString(jobId)); + return getJobStatus(jobId); } catch (Exception e) { LOGGER.error("Error stopping job: " + e); throw new GenericServiceCreateOrUpdateException("jobs", "job status to stop", e); @@ -224,12 +225,13 @@ public void stopJob(Integer jobId) { } @Override - public void pauseJob(Integer jobId) { + public String pauseJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { JobController controller = new ServletInjector().getManagedBean(servletContext, JobController.class); controller.pauseRampJob(Integer.toString(jobId)); + return getJobStatus(jobId); } catch (Exception e) { LOGGER.error("Error pausing job: " + e); throw new GenericServiceCreateOrUpdateException("jobs", "job status to pause", e); @@ -237,12 +239,13 @@ public void pauseJob(Integer jobId) { } @Override - public void resumeJob(Integer jobId) { + public String resumeJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { JobController controller = new ServletInjector().getManagedBean(servletContext, JobController.class); controller.resumeRampJob(Integer.toString(jobId)); + return getJobStatus(jobId); } catch (Exception e) { LOGGER.error("Error resuming job: " + e); throw new GenericServiceCreateOrUpdateException("jobs", "job status to resume", e); @@ -250,12 +253,13 @@ public void resumeJob(Integer jobId) { } @Override - public void killJob(Integer jobId) { + public String killJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { JobController controller = new ServletInjector().getManagedBean(servletContext, JobController.class); controller.killJob(Integer.toString(jobId)); + return getJobStatus(jobId); } catch (Exception e) { LOGGER.error("Error killing job: " + e); throw new GenericServiceCreateOrUpdateException("jobs", "job status to terminate", e); @@ -314,7 +318,7 @@ public static JobInstance addJobToQueue(Project project, CreateJobRequest reques Workload workload = project.getWorkloads().get(0); JobConfiguration jc = workload.getJobConfiguration(); JobQueue queue = jobQueueDao.findOrCreateForProjectId(project.getId()); - JobInstance jobInstance = new JobInstance(workload, buildJobInstanceName(request, workload)); + JobInstance jobInstance = new JobInstance(workload, buildJobInstanceName(request, workload, project)); jobInstance.setScheduledTime(new Date()); jobInstance.setLocation(jc.getLocation()); jobInstance.setLoggingProfile(jc.getLoggingProfile()); @@ -358,9 +362,10 @@ public static JobInstance addJobToQueue(Project project, CreateJobRequest reques return jobInstance; } - private static String buildJobInstanceName(CreateJobRequest request, Workload workload) { + private static String buildJobInstanceName(CreateJobRequest request, Workload workload, Project project) { + String projectName = request.getProjectName() == null ? project.getName() : request.getProjectName(); return StringUtils.isNotEmpty(request.getJobInstanceName()) ? request.getJobInstanceName() - : request.getProjectName() + "_" + workload.getJobConfiguration().getTotalVirtualUsers() + "_users_" + : projectName + "_" + workload.getJobConfiguration().getTotalVirtualUsers() + "_users_" + ReportUtil.getTimestamp(new Date()); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/projects/ProjectServiceV2.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/projects/ProjectServiceV2.java index b841fad00..88c646b42 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/projects/ProjectServiceV2.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/projects/ProjectServiceV2.java @@ -14,6 +14,8 @@ import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + import java.util.Map; public interface ProjectServiceV2 { @@ -35,6 +37,16 @@ public interface ProjectServiceV2 { */ public ProjectContainer getAllProjects(); + /** + * Gets all project names along with projectId + * + * @throws GenericServiceResourceNotFoundException + * if there is an error returning all project names + * + * @return map of project < projectName, projectId > JSON response + */ + public Map getAllProjectNames(); + /** * Gets all specific project * @@ -59,6 +71,17 @@ public interface ProjectServiceV2 { */ public Map createProject(AutomationRequest request); + /** + * Downloads a project's harness XML file + * + * @throws GenericServiceResourceNotFoundException + * if there are errors downloading harness file + * + * @return project's harness XML file + */ + public Map downloadTestScriptForProject(Integer projectId); + + /** * Updates an existing project * diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/projects/ProjectServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/projects/ProjectServiceV2Impl.java index be310e6be..4801df63d 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/projects/ProjectServiceV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/projects/ProjectServiceV2Impl.java @@ -10,6 +10,7 @@ import com.intuit.tank.dao.ProjectDao; import com.intuit.tank.dao.JobRegionDao; import com.intuit.tank.harness.StopBehavior; +import com.intuit.tank.harness.data.HDWorkload; import com.intuit.tank.project.Project; import com.intuit.tank.project.Workload; import com.intuit.tank.project.JobConfiguration; @@ -23,6 +24,7 @@ import com.intuit.tank.rest.mvc.rest.models.projects.AutomationJobRegion; import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; import com.intuit.tank.rest.mvc.rest.util.ProjectServiceUtil; +import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.service.impl.v1.automation.MessageSender; import com.intuit.tank.service.util.ServletInjector; import com.intuit.tank.vm.api.enumerated.ScriptDriver; @@ -30,11 +32,13 @@ import com.intuit.tank.vm.common.TankConstants; import com.intuit.tank.vm.settings.ModificationType; import com.intuit.tank.vm.settings.ModifiedEntityMessage; +import com.intuit.tank.transform.scriptGenerator.ConverterUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.servlet.ServletContext; import java.util.*; @@ -65,6 +69,17 @@ public ProjectContainer getAllProjects(){ } } + @Override + public Map getAllProjectNames(){ + try { + List all = new ProjectDao().findAll(); + return all.stream().collect(Collectors.toMap(Project::getId, Project::getName)); + } catch (Exception e) { + LOGGER.error("Error returning all project names: " + e.getMessage(), e); + throw new GenericServiceResourceNotFoundException("projects", "all project names", e); + } + } + @Override public ProjectTO getProject(Integer projectId){ try { @@ -160,6 +175,27 @@ private void sendMsg(BaseEntity entity, ModificationType type) { sender.sendEvent(new ModifiedEntityMessage(entity.getClass(), entity.getId(), type)); } + @Override + public Map downloadTestScriptForProject(Integer projectId) { + try { + StreamingResponseBody streamingResponse; + Map payload = new HashMap(); + Project p = new ProjectDao().loadScripts(projectId); + if (p == null){ + return null; + } else { + String filename = "project_" + projectId + "_H.xml"; + final HDWorkload hdWorkload = ConverterUtil.convertWorkload(p.getWorkloads().get(0), p.getWorkloads().get(0).getJobConfiguration()); + streamingResponse = ResponseUtil.getXMLStream(hdWorkload); + payload.put(filename, streamingResponse); + return payload; + } + } catch (Exception e){ + LOGGER.error("Error downloading project harness file: " + e.getMessage(), e); + throw new GenericServiceResourceNotFoundException("projects", "project harness file", e); + } + } + public String deleteProject(Integer projectId) { try { ProjectDao dao = new ProjectDao(); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2.java index 935109e92..3d8a69ef4 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2.java @@ -66,6 +66,15 @@ public interface ScriptServiceV2 { */ public ScriptDescriptionContainer getScripts(); + /** + * Gets all script names along with scriptId + * + * @throws GenericServiceResourceNotFoundException + * if there is an error returning all script names + * + * @return map of script < scriptName, scriptId > JSON response + */ + public Map getAllScriptNames(); /** * Downloads a script's Tank XML file associated with scriptID diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2Impl.java index 660807455..7933e504e 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2Impl.java @@ -102,6 +102,17 @@ public ScriptDescriptionContainer getScripts() { } } + @Override + public Map getAllScriptNames(){ + try { + List