From cc890648b95abc8ab39fe0714be6a5336a33201d Mon Sep 17 00:00:00 2001 From: zkofiro Date: Thu, 23 Mar 2023 10:29:43 -0700 Subject: [PATCH 01/73] feat: Add V2 clients --- pom.xml | 6 + rest-mvc/pom.xml | 4 + .../rest/mvc/rest/clients/AgentClient.java | 127 +++++++++++++++ .../rest/mvc/rest/clients/BaseClient.java | 63 ++++++++ .../rest/mvc/rest/clients/DataFileClient.java | 67 ++++++++ .../rest/mvc/rest/clients/FilterClient.java | 85 ++++++++++ .../tank/rest/mvc/rest/clients/JobClient.java | 150 ++++++++++++++++++ .../rest/mvc/rest/clients/ProjectClient.java | 76 +++++++++ .../rest/mvc/rest/clients/ScriptClient.java | 109 +++++++++++++ .../clients/util/RestExceptionHandler.java | 56 +++++++ .../clients/util/RestServiceException.java | 46 ++++++ .../mvc/rest/clients/util/RestUrlBuilder.java | 86 ++++++++++ 12 files changed, 875 insertions(+) create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestExceptionHandler.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestServiceException.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java diff --git a/pom.xml b/pom.xml index d18b0c1c3..de802d0b3 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,7 @@ 2.4-M1-groovy-4.0 2.7.6 5.3.25 + 2.7.6 3.10.1 @@ -844,6 +845,11 @@ spring-boot ${version.spring-boot} + + org.springframework.boot + spring-boot-starter-webflux + ${version.spring-webflux} + diff --git a/rest-mvc/pom.xml b/rest-mvc/pom.xml index 63f745b4d..ea39068a1 100644 --- a/rest-mvc/pom.xml +++ b/rest-mvc/pom.xml @@ -26,6 +26,10 @@ org.springframework.boot spring-boot + + org.springframework.boot + spring-boot-starter-webflux + ${project.groupId} automation-service diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java new file mode 100644 index 000000000..a8293294b --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -0,0 +1,127 @@ +package com.intuit.tank.rest.mvc.rest.clients; + +import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.vm.agent.messages.AgentTestStartData; +import com.intuit.tank.vm.agent.messages.AgentData; +import com.intuit.tank.vm.agent.messages.Headers; + +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.MediaType; +import reactor.core.publisher.Mono; + +import java.util.Map; + +public class AgentClient extends BaseClient{ + + private static final String SERVICE_BASE_URL = "/api/v2/agent"; + + public AgentClient(String serviceUrl) { + super(serviceUrl, null, null); + } + + public AgentClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { + super(serviceUrl, proxyServer, proxyPort); + } + + protected String getServiceBaseUrl() { + return SERVICE_BASE_URL; + } + + + public String getSettings() { + return client.get() + .uri(urlBuilder.buildUrl("/settings")) + .accept(MediaType.APPLICATION_XML) + .retrieve() + .bodyToMono(String.class) + .block(); + } + + public Mono getSupportFiles() { + return client.get() + .uri(urlBuilder.buildUrl("/support-files")) + .retrieve() + .bodyToMono(DataBuffer.class); + } + + public AgentTestStartData agentReady(AgentData agentData) { + return client.post() + .uri(urlBuilder.buildUrl("/ready")) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .body(Mono.just(agentData), AgentData.class) + .retrieve() + .bodyToMono(AgentTestStartData.class) + .block(); + } + + public Headers getHeaders() { + return client.get() + .uri(urlBuilder.buildUrl("/headers")) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(Headers.class) + .block(); + } + + public TankHttpClientDefinitionContainer getClients() { + return client.get() + .uri(urlBuilder.buildUrl("/clients")) + .accept(MediaType.APPLICATION_XML) + .retrieve() + .bodyToMono(TankHttpClientDefinitionContainer.class) + .block(); + } + + public CloudVmStatus getInstanceStatus(String instanceId) { + return client.get() + .uri(urlBuilder.buildUrl("/instance/status/", instanceId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(CloudVmStatus.class) + .block(); + } + + public Void setInstanceStatus(String instanceId, CloudVmStatus status) { + return client.put() + .uri(urlBuilder.buildUrl("/instance/status/", instanceId)) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(status), CloudVmStatus.class) + .retrieve() + .bodyToMono(Void.class) + .block(); + } + + public Void stopInstance(String instanceId) { + return client.get() + .uri(urlBuilder.buildUrl("/instance/stop/", instanceId)) + .retrieve() + .bodyToMono(Void.class) + .block(); + } + + public Void pauseInstance(String instanceId) { + return client.get() + .uri(urlBuilder.buildUrl("/instance/pause/", instanceId)) + .retrieve() + .bodyToMono(Void.class) + .block(); + } + + public Void resumeInstance(String instanceId) { + return client.get() + .uri(urlBuilder.buildUrl("/instance/resume/", instanceId)) + .retrieve() + .bodyToMono(Void.class) + .block(); + } + + public Void killInstance(String instanceId) { + return client.get() + .uri(urlBuilder.buildUrl("/instance/kill/", instanceId)) + .retrieve() + .bodyToMono(Void.class) + .block(); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java new file mode 100644 index 000000000..1b97cc6a5 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java @@ -0,0 +1,63 @@ +package com.intuit.tank.rest.mvc.rest.clients; + +import com.intuit.tank.rest.mvc.rest.clients.util.*; +import reactor.netty.http.client.HttpClient; +import reactor.netty.transport.ProxyProvider; +import org.springframework.http.MediaType; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.WebClient; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.message.ObjectMessage; + +public abstract class BaseClient { + private static final Logger LOGGER = LogManager.getLogger(BaseClient.class); + + protected String baseUrl; + + protected WebClient client; + protected RestExceptionHandler exceptionHandler = new RestExceptionHandler(); + protected RestUrlBuilder urlBuilder; + + public BaseClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { + setBaseUrl(serviceUrl); + if (StringUtils.isNotEmpty(proxyServer)) { + int port = proxyPort != null ? proxyPort : 80; + client = WebClient.builder().clientConnector(new ReactorClientHttpConnector(build(proxyServer, proxyPort))).build(); + } else { + HttpClient httpClient = HttpClient.create().compress(true); + client = WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build(); + + } + LOGGER.info(new ObjectMessage(ImmutableMap.of("Message", "client for url " + baseUrl + ": proxy=" + + (proxyServer != null ? proxyServer + ":" + proxyPort : "none")))); + } + + private HttpClient build(String proxyServer, Integer proxyPort) { + HttpClient httpClient = HttpClient.create() + .tcpConfiguration(tcpClient -> + tcpClient.proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP).host(proxyServer).port(proxyPort))); + return httpClient; + } + + public void setBaseUrl(String baseUrl) { + if (baseUrl != null) { + this.baseUrl = baseUrl + getServiceBaseUrl(); + urlBuilder = new RestUrlBuilder(this.baseUrl); + } + } + + protected abstract String getServiceBaseUrl(); + + public String ping() throws RestServiceException { + return client.get() + .uri(urlBuilder.buildUrl("/ping")) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java new file mode 100644 index 000000000..ec4f87f2e --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java @@ -0,0 +1,67 @@ +package com.intuit.tank.rest.mvc.rest.clients; + +import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; +import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptorContainer; +import org.springframework.http.MediaType; +import reactor.core.publisher.Mono; + +import java.util.Map; + +public class DataFileClient extends BaseClient{ + + private static final String SERVICE_BASE_URL = "/api/v2/datafiles"; + + public DataFileClient(String serviceUrl) { + super(serviceUrl, null, null); + } + + public DataFileClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { + super(serviceUrl, proxyServer, proxyPort); + } + + protected String getServiceBaseUrl() { + return SERVICE_BASE_URL; + } + + + public DataFileDescriptorContainer getDatafiles() { + return client.get() + .uri(baseUrl) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(DataFileDescriptorContainer.class) + .block(); + } + + public DataFileDescriptor getDatafile(Integer datafileId) { + return client.get() + .uri(urlBuilder.buildUrl("", datafileId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(DataFileDescriptor.class) + .block(); + } + + public String getDatafileContent(Integer id, Integer offset, Integer lines) { + return client.get() + .uri(uriBuilder -> uriBuilder + .path(urlBuilder.buildUrl("/content")) + .queryParam("id", id) + .queryParam("offset", offset) + .queryParam("lines", lines) + .build()) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } + + public String deleteDatafile(Integer datafileID) { + return client.delete() + .uri(urlBuilder.buildUrl("", datafileID)) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java new file mode 100644 index 000000000..0f749dd31 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java @@ -0,0 +1,85 @@ +package com.intuit.tank.rest.mvc.rest.clients; + +import com.intuit.tank.rest.mvc.rest.models.filters.FilterContainer; +import com.intuit.tank.rest.mvc.rest.models.filters.FilterGroupContainer; +import com.intuit.tank.rest.mvc.rest.models.filters.FilterGroupTO; +import com.intuit.tank.rest.mvc.rest.models.filters.FilterTO; +import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; +import org.springframework.http.MediaType; +import reactor.core.publisher.Mono; + +import java.util.Map; + +public class FilterClient extends BaseClient{ + + private static final String SERVICE_BASE_URL = "/api/v2/filters"; + + public FilterClient(String serviceUrl) { + super(serviceUrl, null, null); + } + + public FilterClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { + super(serviceUrl, proxyServer, proxyPort); + } + + protected String getServiceBaseUrl() { + return SERVICE_BASE_URL; + } + + + public FilterContainer getFilters() { + return client.get() + .uri(baseUrl) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(FilterContainer.class) + .block(); + } + + public FilterGroupContainer getFilterGroups() { + return client.get() + .uri(urlBuilder.buildUrl("/groups")) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(FilterGroupContainer.class) + .block(); + } + + public FilterTO getFilter(Integer filterId) { + return client.get() + .uri(urlBuilder.buildUrl("", filterId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(FilterTO.class) + .block(); + } + + public FilterGroupTO getFilterGroup(Integer filterGroupId) { + return client.get() + .uri(urlBuilder.buildUrl("", filterGroupId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(FilterGroupTO.class) + .block(); + } + + public String deleteFilter(Integer filterId) { + return client.delete() + .uri(urlBuilder.buildUrl("", filterId)) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } + + public String deleteFilterGroup(Integer filterGroupId) { + return client.delete() + .uri(urlBuilder.buildUrl("", filterGroupId)) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java new file mode 100644 index 000000000..f18fb1733 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java @@ -0,0 +1,150 @@ +package com.intuit.tank.rest.mvc.rest.clients; + +import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; +import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; +import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import org.springframework.http.MediaType; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.Map; + +public class JobClient extends BaseClient{ + + private static final String SERVICE_BASE_URL = "/api/v2/jobs"; + + public JobClient(String serviceUrl) { + super(serviceUrl, null, null); + } + + public JobClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { + super(serviceUrl, proxyServer, proxyPort); + } + + protected String getServiceBaseUrl() { + return SERVICE_BASE_URL; + } + + + public JobContainer getAllJobs() { + return client.get() + .uri(baseUrl) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(JobContainer.class) + .block(); + } + + public JobTO getJob(Integer jobId) { + return client.get() + .uri(urlBuilder.buildUrl("", jobId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(JobTO.class) + .block(); + } + + public JobContainer getJobsByProject(Integer projectId) { + return client.get() + .uri(urlBuilder.buildUrl("/project", projectId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(JobContainer.class) + .block(); + } + + public Map createJob(CreateJobRequest request) { + return client.post() + .uri(baseUrl) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .body(Mono.just(request), CreateJobRequest.class) + .retrieve() + .bodyToMono(Map.class) + .block(); + } + + public List> getAllJobStatus() { + return client.get() + .uri(urlBuilder.buildUrl("/status")) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(List.class) + .block(); + } + + public String getJobStatus(Integer jobId) { + return client.get() + .uri(urlBuilder.buildUrl("/status", jobId)) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } + + public String getJobVMStatuses(String jobId) { + return client.get() + .uri(urlBuilder.buildUrl("/instance-status", jobId)) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } + + public CloudVmStatusContainer deleteProject(Integer projectId) { + return client.delete() + .uri(urlBuilder.buildUrl("", projectId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(CloudVmStatusContainer.class) + .block(); + } + + // Job Status Setters + + public Void startJob(Integer jobId) { + return client.get() + .uri(urlBuilder.buildUrl("/start", jobId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(Void.class) + .block(); + } + + public Void stopJob(Integer jobId) { + return client.get() + .uri(urlBuilder.buildUrl("/stop", jobId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(Void.class) + .block(); + } + + public Void pauseJob(Integer jobId) { + return client.get() + .uri(urlBuilder.buildUrl("/pause", jobId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(Void.class) + .block(); + } + + public Void resumeJob(Integer jobId) { + return client.get() + .uri(urlBuilder.buildUrl("/resume", jobId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(Void.class) + .block(); + } + + public Void killJob(Integer jobId) { + return client.get() + .uri(urlBuilder.buildUrl("/kill", jobId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(Void.class) + .block(); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java new file mode 100644 index 000000000..bdd6ae8f2 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java @@ -0,0 +1,76 @@ +package com.intuit.tank.rest.mvc.rest.clients; + +import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; +import org.springframework.http.MediaType; +import reactor.core.publisher.Mono; + +import java.util.Map; + +public class ProjectClient extends BaseClient{ + + private static final String SERVICE_BASE_URL = "/api/v2/projects"; + + public ProjectClient(String serviceUrl) { + super(serviceUrl, null, null); + } + + public ProjectClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { + super(serviceUrl, proxyServer, proxyPort); + } + + protected String getServiceBaseUrl() { + return SERVICE_BASE_URL; + } + + + public ProjectContainer getProjects() { + return client.get() + .uri(baseUrl) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(ProjectContainer.class) + .block(); + } + + public ProjectTO getProject(Integer projectId) { + return client.get() + .uri(urlBuilder.buildUrl("", projectId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(ProjectTO.class) + .block(); + } + + public Map createProject(AutomationRequest request) { + return client.post() + .uri(baseUrl) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .body(Mono.just(request), AutomationRequest.class) + .retrieve() + .bodyToMono(Map.class) + .block(); + } + + public Map updateProject(AutomationRequest request) { + return client.put() + .uri(baseUrl) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .body(Mono.just(request), AutomationRequest.class) + .retrieve() + .bodyToMono(Map.class) + .block(); + } + + public String deleteProject(Integer projectId) { + return client.delete() + .uri(urlBuilder.buildUrl("", projectId)) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java new file mode 100644 index 000000000..2aa21c8d0 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java @@ -0,0 +1,109 @@ +package com.intuit.tank.rest.mvc.rest.clients; + +import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; +import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; +import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; +import org.springframework.http.MediaType; +import reactor.core.publisher.Mono; + +import java.util.Map; + +public class ScriptClient extends BaseClient{ + + private static final String SERVICE_BASE_URL = "/api/v2/projects"; + + public ScriptClient(String serviceUrl) { + super(serviceUrl, null, null); + } + + public ScriptClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { + super(serviceUrl, proxyServer, proxyPort); + } + + protected String getServiceBaseUrl() { + return SERVICE_BASE_URL; + } + + + public ScriptDescriptionContainer getScripts() { + return client.get() + .uri(baseUrl) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(ScriptDescriptionContainer.class) + .block(); + } + + public ScriptTO getScript(Integer scriptId) { + return client.get() + .uri(urlBuilder.buildUrl("", scriptId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(ScriptTO.class) + .block(); + } + + public ScriptTO createScript(ScriptTO scriptTo) { + return client.post() + .uri(baseUrl) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .body(Mono.just(scriptTo), ScriptTO.class) + .retrieve() + .bodyToMono(ScriptTO.class) + .block(); + } + + public String deleteScript(Integer scriptId) { + return client.delete() + .uri(urlBuilder.buildUrl("", scriptId)) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } + + // External Scripts + + public ExternalScriptContainer getExternalScripts() { + return client.get() + .uri(urlBuilder.buildUrl("/external")) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(ExternalScriptContainer.class) + .block(); + } + + public ExternalScriptTO getExternalScript(Integer externalScriptId) { + return client.get() + .uri(urlBuilder.buildUrl("/external", externalScriptId)) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(ExternalScriptTO.class) + .block(); + } + + public ExternalScriptTO createExternalScript(ExternalScriptTO script) { + return client.post() + .uri(urlBuilder.buildUrl("/external")) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .body(Mono.just(script), ExternalScriptTO.class) + .retrieve() + .bodyToMono(ExternalScriptTO.class) + .block(); + } + + public String deleteExternalScript(Integer externalScriptId) { + return client.delete() + .uri(urlBuilder.buildUrl("/external", externalScriptId)) + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToMono(String.class) + .block(); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestExceptionHandler.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestExceptionHandler.java new file mode 100644 index 000000000..d9d787018 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestExceptionHandler.java @@ -0,0 +1,56 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.clients.util; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.ws.rs.core.Response; + +/** + * RestExceptionHandler + * + * @author dangleton + * + */ +public class RestExceptionHandler { + + private static final Logger LOG = LogManager.getLogger(RestExceptionHandler.class); + + public void checkStatusCode(Response response) throws RestServiceException { + if (response.getStatus() >= 400) { + LOG.error("Got rest response status code " + response.getStatus() + " from location " + + response.getLocation()); + String msg = response.readEntity(String.class); + if (msg == null) { + msg = getMessageForCode(response.getStatus()); + } + throw new RestServiceException(msg, response.getStatus()); + + } + } + + /** + * @param status + * @return + */ + private String getMessageForCode(int status) { + String result = null; + switch (status) { + case 400: + result = "The request could not be understood by the server due to malformed syntax."; + break; + case 401: + result = "The request requires user authentication."; + break; + case 404: + result = "Resource not found."; + break; + + default: + result = "Error processing request."; + } + return result; + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestServiceException.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestServiceException.java new file mode 100644 index 000000000..a81b76291 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestServiceException.java @@ -0,0 +1,46 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.clients.util; + +/* + * #%L + * Rest Client Common + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +/** + * ServiceException + * + * @author dangleton + * + */ +public class RestServiceException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private int statusCode; + + /** + * @param arg0 + */ + public RestServiceException(String message, int statusCode) { + super(message); + this.statusCode = statusCode; + } + + /** + * @return the statusCode + */ + public int getStatusCode() { + return statusCode; + } + +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java new file mode 100644 index 000000000..4d49cfa8c --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java @@ -0,0 +1,86 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.clients.util; + +/* + * #%L + * Rest Client Common + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import org.apache.commons.lang3.StringUtils; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * RestUrlBuilder + * + * @author dangleton + * + */ +public class RestUrlBuilder { + + private String baseUrl; + + /** + * @param baseUrl + */ + public RestUrlBuilder(@Nonnull String baseUrl) { + this.baseUrl = StringUtils.removeEnd(baseUrl, "/"); + } + + /** + * Builds the url with the specified methodName. + * + * @param methodName + * the methodName + * @return the url. + */ + @Nonnull + public String buildUrl(@Nonnull String methodName) { + return buildUrl(methodName, (Object[]) null); + } + + /** + * Builds the url with the specified methodName and parameter. + * + * @param methodName + * the methodName + * @param parameters + * the parameter value + * @return the url. + */ + @Nonnull + public String buildUrl(@Nullable String methodName, @Nullable Object... parameters) { + StringBuilder sb = new StringBuilder(baseUrl); + if (methodName != null) { + if (!methodName.startsWith("/")) { + sb.append('/'); + } + sb.append(StringUtils.removeEnd(methodName, "/")); + + } + if (parameters != null) { + for (Object parameter : parameters) { + if (parameter != null) { + String s = parameter.toString(); + if (!s.startsWith("/")) { + sb.append('/'); + } + sb.append(s); + } + } + } + return sb.toString(); + } + +} From 0f5989d6ff86ae2655ea28af3a8e032f59a12b45 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Thu, 23 Mar 2023 10:38:46 -0700 Subject: [PATCH 02/73] fix: clean up + switching to webclient exception handling --- .../rest/mvc/rest/clients/AgentClient.java | 7 +++ .../rest/mvc/rest/clients/BaseClient.java | 7 +++ .../rest/mvc/rest/clients/DataFileClient.java | 7 +++ .../rest/mvc/rest/clients/FilterClient.java | 10 +++- .../tank/rest/mvc/rest/clients/JobClient.java | 7 +++ .../rest/mvc/rest/clients/ProjectClient.java | 7 +++ .../rest/mvc/rest/clients/ScriptClient.java | 10 +++- .../clients/util/RestExceptionHandler.java | 56 ------------------- .../clients/util/RestServiceException.java | 46 --------------- .../mvc/rest/clients/util/RestUrlBuilder.java | 18 ++---- 10 files changed, 54 insertions(+), 121 deletions(-) delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestExceptionHandler.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestServiceException.java diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java index a8293294b..7da7b8f55 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -1,3 +1,10 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package com.intuit.tank.rest.mvc.rest.clients; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java index 1b97cc6a5..81273b1ca 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java @@ -1,3 +1,10 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package com.intuit.tank.rest.mvc.rest.clients; import com.intuit.tank.rest.mvc.rest.clients.util.*; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java index ec4f87f2e..930d70f33 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java @@ -1,3 +1,10 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package com.intuit.tank.rest.mvc.rest.clients; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java index 0f749dd31..224607bc9 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java @@ -1,12 +1,16 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package com.intuit.tank.rest.mvc.rest.clients; import com.intuit.tank.rest.mvc.rest.models.filters.FilterContainer; import com.intuit.tank.rest.mvc.rest.models.filters.FilterGroupContainer; import com.intuit.tank.rest.mvc.rest.models.filters.FilterGroupTO; import com.intuit.tank.rest.mvc.rest.models.filters.FilterTO; -import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; -import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; -import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java index f18fb1733..548cc6367 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java @@ -1,3 +1,10 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package com.intuit.tank.rest.mvc.rest.clients; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java index bdd6ae8f2..ce90bff5a 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java @@ -1,3 +1,10 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package com.intuit.tank.rest.mvc.rest.clients; import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java index 2aa21c8d0..590a949df 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java @@ -1,8 +1,12 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package com.intuit.tank.rest.mvc.rest.clients; -import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; -import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; -import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestExceptionHandler.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestExceptionHandler.java deleted file mode 100644 index d9d787018..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestExceptionHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank.rest.mvc.rest.clients.util; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.ws.rs.core.Response; - -/** - * RestExceptionHandler - * - * @author dangleton - * - */ -public class RestExceptionHandler { - - private static final Logger LOG = LogManager.getLogger(RestExceptionHandler.class); - - public void checkStatusCode(Response response) throws RestServiceException { - if (response.getStatus() >= 400) { - LOG.error("Got rest response status code " + response.getStatus() + " from location " - + response.getLocation()); - String msg = response.readEntity(String.class); - if (msg == null) { - msg = getMessageForCode(response.getStatus()); - } - throw new RestServiceException(msg, response.getStatus()); - - } - } - - /** - * @param status - * @return - */ - private String getMessageForCode(int status) { - String result = null; - switch (status) { - case 400: - result = "The request could not be understood by the server due to malformed syntax."; - break; - case 401: - result = "The request requires user authentication."; - break; - case 404: - result = "Resource not found."; - break; - - default: - result = "Error processing request."; - } - return result; - } -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestServiceException.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestServiceException.java deleted file mode 100644 index a81b76291..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestServiceException.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank.rest.mvc.rest.clients.util; - -/* - * #%L - * Rest Client Common - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -/** - * ServiceException - * - * @author dangleton - * - */ -public class RestServiceException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - private int statusCode; - - /** - * @param arg0 - */ - public RestServiceException(String message, int statusCode) { - super(message); - this.statusCode = statusCode; - } - - /** - * @return the statusCode - */ - public int getStatusCode() { - return statusCode; - } - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java index 4d49cfa8c..2f2ee3ab8 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java @@ -1,20 +1,12 @@ /** - * Copyright 2011 Intuit Inc. All Rights Reserved + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ package com.intuit.tank.rest.mvc.rest.clients.util; -/* - * #%L - * Rest Client Common - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ import org.apache.commons.lang3.StringUtils; From efe65c61b124cf9642d881b7ccd411519712a0ea Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 24 Mar 2023 09:38:50 -0700 Subject: [PATCH 03/73] fix: better exception handling --- .../rest/mvc/rest/clients/AgentClient.java | 50 ++++++++++++++++- .../rest/mvc/rest/clients/BaseClient.java | 9 +++- .../rest/mvc/rest/clients/DataFileClient.java | 19 ++++++- .../rest/mvc/rest/clients/FilterClient.java | 25 +++++++++ .../tank/rest/mvc/rest/clients/JobClient.java | 53 +++++++++++++++++++ .../rest/mvc/rest/clients/ProjectClient.java | 35 ++++++++++++ .../rest/mvc/rest/clients/ScriptClient.java | 33 ++++++++++++ .../rest/clients/util/ClientException.java | 52 ++++++++++++++++++ .../mvc/rest/clients/util/RestUrlBuilder.java | 6 --- .../errors/GenericExceptionHandler.java | 8 ++- 10 files changed, 277 insertions(+), 13 deletions(-) create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/ClientException.java diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java index 7da7b8f55..807dcc401 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -7,6 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.clients; +import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.vm.agent.messages.AgentTestStartData; @@ -14,6 +15,7 @@ import com.intuit.tank.vm.agent.messages.Headers; import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; @@ -41,6 +43,10 @@ public String getSettings() { .uri(urlBuilder.buildUrl("/settings")) .accept(MediaType.APPLICATION_XML) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } @@ -49,6 +55,10 @@ public Mono getSupportFiles() { return client.get() .uri(urlBuilder.buildUrl("/support-files")) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(DataBuffer.class); } @@ -59,6 +69,10 @@ public AgentTestStartData agentReady(AgentData agentData) { .accept(MediaType.APPLICATION_JSON) .body(Mono.just(agentData), AgentData.class) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(AgentTestStartData.class) .block(); } @@ -68,6 +82,10 @@ public Headers getHeaders() { .uri(urlBuilder.buildUrl("/headers")) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Headers.class) .block(); } @@ -77,6 +95,10 @@ public TankHttpClientDefinitionContainer getClients() { .uri(urlBuilder.buildUrl("/clients")) .accept(MediaType.APPLICATION_XML) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(TankHttpClientDefinitionContainer.class) .block(); } @@ -86,16 +108,24 @@ public CloudVmStatus getInstanceStatus(String instanceId) { .uri(urlBuilder.buildUrl("/instance/status/", instanceId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(CloudVmStatus.class) .block(); } - public Void setInstanceStatus(String instanceId, CloudVmStatus status) { + public Void setInstanceStatus(String instanceId, CloudVmStatus VmStatus) { return client.put() .uri(urlBuilder.buildUrl("/instance/status/", instanceId)) .contentType(MediaType.APPLICATION_JSON) - .body(Mono.just(status), CloudVmStatus.class) + .body(Mono.just(VmStatus), CloudVmStatus.class) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } @@ -104,6 +134,10 @@ public Void stopInstance(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/stop/", instanceId)) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } @@ -112,6 +146,10 @@ public Void pauseInstance(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/pause/", instanceId)) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } @@ -120,6 +158,10 @@ public Void resumeInstance(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/resume/", instanceId)) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } @@ -128,6 +170,10 @@ public Void killInstance(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/kill/", instanceId)) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java index 81273b1ca..f32d75084 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java @@ -8,8 +8,10 @@ package com.intuit.tank.rest.mvc.rest.clients; import com.intuit.tank.rest.mvc.rest.clients.util.*; +import reactor.core.publisher.Mono; import reactor.netty.http.client.HttpClient; import reactor.netty.transport.ProxyProvider; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.reactive.function.client.WebClient; @@ -26,7 +28,6 @@ public abstract class BaseClient { protected String baseUrl; protected WebClient client; - protected RestExceptionHandler exceptionHandler = new RestExceptionHandler(); protected RestUrlBuilder urlBuilder; public BaseClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { @@ -59,11 +60,15 @@ public void setBaseUrl(String baseUrl) { protected abstract String getServiceBaseUrl(); - public String ping() throws RestServiceException { + public String ping() { return client.get() .uri(urlBuilder.buildUrl("/ping")) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java index 930d70f33..1b1979957 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java @@ -7,13 +7,12 @@ */ package com.intuit.tank.rest.mvc.rest.clients; +import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptorContainer; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; -import java.util.Map; - public class DataFileClient extends BaseClient{ private static final String SERVICE_BASE_URL = "/api/v2/datafiles"; @@ -36,6 +35,10 @@ public DataFileDescriptorContainer getDatafiles() { .uri(baseUrl) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(DataFileDescriptorContainer.class) .block(); } @@ -45,6 +48,10 @@ public DataFileDescriptor getDatafile(Integer datafileId) { .uri(urlBuilder.buildUrl("", datafileId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(DataFileDescriptor.class) .block(); } @@ -59,6 +66,10 @@ public String getDatafileContent(Integer id, Integer offset, Integer lines) { .build()) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } @@ -68,6 +79,10 @@ public String deleteDatafile(Integer datafileID) { .uri(urlBuilder.buildUrl("", datafileID)) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java index 224607bc9..324546a21 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java @@ -7,6 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.clients; +import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.filters.FilterContainer; import com.intuit.tank.rest.mvc.rest.models.filters.FilterGroupContainer; import com.intuit.tank.rest.mvc.rest.models.filters.FilterGroupTO; @@ -38,6 +39,10 @@ public FilterContainer getFilters() { .uri(baseUrl) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(FilterContainer.class) .block(); } @@ -47,6 +52,10 @@ public FilterGroupContainer getFilterGroups() { .uri(urlBuilder.buildUrl("/groups")) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(FilterGroupContainer.class) .block(); } @@ -56,6 +65,10 @@ public FilterTO getFilter(Integer filterId) { .uri(urlBuilder.buildUrl("", filterId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(FilterTO.class) .block(); } @@ -65,6 +78,10 @@ public FilterGroupTO getFilterGroup(Integer filterGroupId) { .uri(urlBuilder.buildUrl("", filterGroupId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(FilterGroupTO.class) .block(); } @@ -74,6 +91,10 @@ public String deleteFilter(Integer filterId) { .uri(urlBuilder.buildUrl("", filterId)) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } @@ -83,6 +104,10 @@ public String deleteFilterGroup(Integer filterGroupId) { .uri(urlBuilder.buildUrl("", filterGroupId)) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java index 548cc6367..ca955ecb4 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java @@ -7,6 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.clients; +import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; @@ -39,6 +40,10 @@ public JobContainer getAllJobs() { .uri(baseUrl) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(JobContainer.class) .block(); } @@ -48,6 +53,10 @@ public JobTO getJob(Integer jobId) { .uri(urlBuilder.buildUrl("", jobId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(JobTO.class) .block(); } @@ -57,6 +66,10 @@ public JobContainer getJobsByProject(Integer projectId) { .uri(urlBuilder.buildUrl("/project", projectId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(JobContainer.class) .block(); } @@ -68,6 +81,10 @@ public Map createJob(CreateJobRequest request) { .accept(MediaType.APPLICATION_JSON) .body(Mono.just(request), CreateJobRequest.class) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Map.class) .block(); } @@ -77,6 +94,10 @@ public List> getAllJobStatus() { .uri(urlBuilder.buildUrl("/status")) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(List.class) .block(); } @@ -86,6 +107,10 @@ public String getJobStatus(Integer jobId) { .uri(urlBuilder.buildUrl("/status", jobId)) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } @@ -95,6 +120,10 @@ public String getJobVMStatuses(String jobId) { .uri(urlBuilder.buildUrl("/instance-status", jobId)) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } @@ -104,6 +133,10 @@ public CloudVmStatusContainer deleteProject(Integer projectId) { .uri(urlBuilder.buildUrl("", projectId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(CloudVmStatusContainer.class) .block(); } @@ -115,6 +148,10 @@ public Void startJob(Integer jobId) { .uri(urlBuilder.buildUrl("/start", jobId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } @@ -124,6 +161,10 @@ public Void stopJob(Integer jobId) { .uri(urlBuilder.buildUrl("/stop", jobId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } @@ -133,6 +174,10 @@ public Void pauseJob(Integer jobId) { .uri(urlBuilder.buildUrl("/pause", jobId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } @@ -142,6 +187,10 @@ public Void resumeJob(Integer jobId) { .uri(urlBuilder.buildUrl("/resume", jobId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } @@ -151,6 +200,10 @@ public Void killJob(Integer jobId) { .uri(urlBuilder.buildUrl("/kill", jobId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Void.class) .block(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java index ce90bff5a..99774bfde 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java @@ -7,9 +7,11 @@ */ package com.intuit.tank.rest.mvc.rest.clients; +import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; @@ -37,15 +39,36 @@ public ProjectContainer getProjects() { .uri(baseUrl) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(ProjectContainer.class) .block(); } + public Map getProjectNames() { + return client.get() + .uri(urlBuilder.buildUrl("/names")) + .accept(MediaType.APPLICATION_JSON) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(Map.class) + .block(); + } + public ProjectTO getProject(Integer projectId) { return client.get() .uri(urlBuilder.buildUrl("", projectId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(ProjectTO.class) .block(); } @@ -57,6 +80,10 @@ public Map createProject(AutomationRequest request) { .accept(MediaType.APPLICATION_JSON) .body(Mono.just(request), AutomationRequest.class) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Map.class) .block(); } @@ -68,6 +95,10 @@ public Map updateProject(AutomationRequest request) { .accept(MediaType.APPLICATION_JSON) .body(Mono.just(request), AutomationRequest.class) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(Map.class) .block(); } @@ -77,6 +108,10 @@ public String deleteProject(Integer projectId) { .uri(urlBuilder.buildUrl("", projectId)) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java index 590a949df..1b6947df0 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java @@ -7,6 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.clients; +import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; @@ -38,6 +39,10 @@ public ScriptDescriptionContainer getScripts() { .uri(baseUrl) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(ScriptDescriptionContainer.class) .block(); } @@ -47,6 +52,10 @@ public ScriptTO getScript(Integer scriptId) { .uri(urlBuilder.buildUrl("", scriptId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(ScriptTO.class) .block(); } @@ -58,6 +67,10 @@ public ScriptTO createScript(ScriptTO scriptTo) { .accept(MediaType.APPLICATION_JSON) .body(Mono.just(scriptTo), ScriptTO.class) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(ScriptTO.class) .block(); } @@ -67,6 +80,10 @@ public String deleteScript(Integer scriptId) { .uri(urlBuilder.buildUrl("", scriptId)) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } @@ -78,6 +95,10 @@ public ExternalScriptContainer getExternalScripts() { .uri(urlBuilder.buildUrl("/external")) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(ExternalScriptContainer.class) .block(); } @@ -87,6 +108,10 @@ public ExternalScriptTO getExternalScript(Integer externalScriptId) { .uri(urlBuilder.buildUrl("/external", externalScriptId)) .accept(MediaType.APPLICATION_JSON) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(ExternalScriptTO.class) .block(); } @@ -98,6 +123,10 @@ public ExternalScriptTO createExternalScript(ExternalScriptTO script) { .accept(MediaType.APPLICATION_JSON) .body(Mono.just(script), ExternalScriptTO.class) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(ExternalScriptTO.class) .block(); } @@ -107,6 +136,10 @@ public String deleteExternalScript(Integer externalScriptId) { .uri(urlBuilder.buildUrl("/external", externalScriptId)) .accept(MediaType.TEXT_PLAIN) .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) .bodyToMono(String.class) .block(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/ClientException.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/ClientException.java new file mode 100644 index 000000000..ae199e8cc --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/ClientException.java @@ -0,0 +1,52 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.clients.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.intuit.tank.rest.mvc.rest.services.projects.ProjectServiceV2Impl; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Map; + +public class ClientException extends RuntimeException { + + private static final Logger LOGGER = LogManager.getLogger(ClientException.class); + + private static final long serialVersionUID = 1L; + + private int statusCode; + + private String message; + + public ClientException(String message, int statusCode) { + super(message); + this.statusCode = statusCode; + this.message = message; + } + + public int getStatusCode() { + return statusCode; + } + + public String getMessage() { + return message; + } + + public String getErrorMessage() { + try { + ObjectMapper mapper = new ObjectMapper(); + Map map = mapper.readValue(this.message, Map.class); + return map.get("message"); + } catch (JsonProcessingException e) { + LOGGER.error("ClientException error processing JSON error message"); + return message; + } + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java index 2f2ee3ab8..c246da321 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/util/RestUrlBuilder.java @@ -13,12 +13,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -/** - * RestUrlBuilder - * - * @author dangleton - * - */ public class RestUrlBuilder { private String baseUrl; 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 b04a2c6a4..006000430 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 @@ -7,6 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.controllers.errors; +import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; import org.springframework.beans.factory.annotation.Value; @@ -41,6 +42,11 @@ public SimpleErrorResponse handleResourceDeleteException(GenericServiceDeleteExc return genericErrorResponse(HttpStatus.NOT_FOUND, "Resource could not be deleted: " + e.getResource(), e); } + @ExceptionHandler + public SimpleErrorResponse handleClientException(ClientException e) { + return genericErrorResponse(HttpStatus.valueOf(e.getStatusCode()), e.getErrorMessage(), e); + } + @ExceptionHandler public SimpleErrorResponse handleOtherErrors(Throwable t) { LOGGER.error("handling an unexpected exception", t); @@ -49,7 +55,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); } } From 66d2ca40b51d0172060c5f040a8cc447f5cf7b93 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Mon, 20 Mar 2023 12:01:49 -0700 Subject: [PATCH 04/73] feat: [SRE-26521] upload/download for scripts/datafiles fix: supports both normal and gzip file uploads fix: updating get specific script to script JSON description, download handles content fix: updated max file size and added exception handling for file exceptions fix: set debug to false fix: group all exception handlers fix: updating prefix fix: unneeded file fix: reverting file change Revert "fix: reverting file change" This reverts commit 0ba90f6430d5a26a202cf6ad075a4b3b92f31193. fix: revert file fix: reverting file as well fix: detailed error msg for incorrect request --- .../rest/controllers/DataFileController.java | 48 ++++++ .../rest/controllers/ScriptController.java | 135 ++++++++++++++-- .../errors/GenericExceptionHandler.java | 22 +++ .../errors/RestRequestExceptionHandler.java | 18 --- .../services/datafiles/DataFileServiceV2.java | 38 +++++ .../datafiles/DataFileServiceV2Impl.java | 70 +++++++- .../services/scripts/ScriptServiceV2.java | 93 +++++++++-- .../services/scripts/ScriptServiceV2Impl.java | 151 +++++++++++++++++- .../mvc/rest/util/DataFileServiceUtil.java | 7 +- .../tank/rest/mvc/rest/util/ResponseUtil.java | 11 +- .../rest/mvc/rest/util/ServletInjector.java | 29 ---- rest-mvc/src/main/resources/application.yml | 4 + .../controllers/DataFileControllerTest.java | 38 ++++- .../controllers/ScriptControllerTest.java | 83 +++++++++- web/web_ui/src/main/webapp/WEB-INF/web.xml | 6 + 15 files changed, 656 insertions(+), 97 deletions(-) delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/RestRequestExceptionHandler.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java 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 7d57d12ce..ebe0ef441 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 @@ -14,6 +14,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; @@ -29,6 +30,7 @@ import javax.annotation.Resource; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.Map; import java.util.Objects; @RestController @@ -89,6 +91,52 @@ public ResponseEntity getDatafileContent(@RequestParam(required = true) return ResponseEntity.notFound().build(); } + @RequestMapping(value = "/download/{datafileId}", method = RequestMethod.GET) + @Operation(description = "Downloads a datafile with the corresponding datafile ID", summary = "Download a datafile") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully downloaded the datafile", content = @Content), + @ApiResponse(responseCode = "404", description = "Datafile could not be found", content = @Content) + }) + public ResponseEntity downloadDatafile(@PathVariable @Parameter(description = "Datafile ID", required = true) Integer datafileId) throws IOException { + Map response = dataFileService.downloadDatafile(datafileId); + 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 = "/upload", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) + @Operation(description = "Uploads a datafile to Tank (supports gzip files) \n\n " + + "Examples: \n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/datafiles/upload'\n\n" + + "\n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/datafiles/upload?id='\n\n" + + "\n\n" + + " gzip \n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -H 'Content-Encoding: gzip' -F \"file=@.gz\" 'https://{tank-base-url}/api/v2/datafiles/upload'\n\n" + + "Notes: \n\n " + + " - Datafile id is an optional parameter \n\n" + + " - Passing in an existing Tank Datafile ID will overwrite the existing datafile in Tank, but will otherwise create a new datafile", summary = "Upload datafile to Tank") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Successfully uploaded datafile", content = @Content), + @ApiResponse(responseCode = "400", description = "Datafile could not be uploaded", content = @Content) + }) + public ResponseEntity> uploadDatafile(@RequestHeader(value = HttpHeaders.CONTENT_ENCODING, required = false) @Parameter(description = "Content-Encoding", required = false) String contentEncoding, + @RequestParam(required = false) @Parameter(description = "Existing Datafile ID (optional)", required = false) Integer id, + @RequestParam(value = "file", required = true) @Parameter(schema = @Schema(type = "string", format = "binary", description = "Datafile file")) MultipartFile file) throws IOException{ + Map response = dataFileService.uploadDatafile(id, contentEncoding, file); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + @RequestMapping(value = "/{datafileID}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) @ResponseStatus(HttpStatus.NO_CONTENT) @Operation(description = "Deletes a specific datafile by datafile ID", summary = "Delete a datafile") 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 b762b705c..1ef41cf07 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 @@ -9,24 +9,31 @@ import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescription; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; import com.intuit.tank.rest.mvc.rest.services.scripts.ScriptServiceV2; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import java.io.*; import java.net.URI; +import java.util.Map; import java.util.Objects; import javax.annotation.Resource; @@ -47,8 +54,8 @@ public ResponseEntity ping() { } @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found all scripts"), - @ApiResponse(responseCode = "404", description = "All scripts could not be found", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully found all script descriptions"), + @ApiResponse(responseCode = "404", description = "All scripts descriptions could not be found", content = @Content) }) @RequestMapping(method = RequestMethod.GET) @Operation(description = "Returns all script descriptions", summary = "Get all script descriptions") @@ -56,14 +63,14 @@ public ResponseEntity getScripts() { return new ResponseEntity<>(scriptService.getScripts(), HttpStatus.OK); } - @RequestMapping(value = "/{scriptId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_XML_VALUE }) + @RequestMapping(value = "/{scriptId}", method = RequestMethod.GET) @Operation(description = "Returns a specific script description by script ID", summary = "Get a specific script description") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found script"), - @ApiResponse(responseCode = "404", description = "Script could not be found", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully found script description"), + @ApiResponse(responseCode = "404", description = "Script description could not be found", content = @Content) }) - public ResponseEntity getScript(@PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) { - ScriptTO script = scriptService.getScript(scriptId); + public ResponseEntity getScript(@PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) { + ScriptDescription script = scriptService.getScript(scriptId); if (script != null){ return new ResponseEntity<>(script, HttpStatus.OK); } @@ -85,14 +92,85 @@ public ResponseEntity createScript( return new ResponseEntity<>(savedScript, responseHeaders, HttpStatus.CREATED); } - @RequestMapping(value = "/{scriptID}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) + @RequestMapping(value = "/download/{scriptId}", method = RequestMethod.GET) + @Operation(description = "Downloads the Tank XML file for a script with the corresponding script ID", summary = "Download the Tank XML script file") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully downloaded the Tank XML script file", content = @Content), + @ApiResponse(responseCode = "404", description = "Tank XML script file could not be found", content = @Content) + }) + public ResponseEntity downloadScript(@PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) throws IOException { + Map response = scriptService.downloadScript(scriptId); + 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 = "/harness/download/{scriptId}", method = RequestMethod.GET) + @Operation(description = "Downloads the Tank Harness file for a script with the corresponding script ID", summary = "Download the Tank Harness script file") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully downloaded the Tank Harness script file", content = @Content), + @ApiResponse(responseCode = "404", description = "Tank Harness script file could not be found", content = @Content) + }) + public ResponseEntity downloadHarnessScript(@PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) throws IOException { + Map response = scriptService.downloadHarnessScript(scriptId); + 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 = "/upload", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) + @Operation(description = "Uploads a script XML file output generated by the Tank Proxy Package (supports gzip files) \n\n " + + "Examples: \n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/scripts/upload' \n\n" + + "\n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/scripts/upload?id=&name='\n\n" + + "\n\n" + + " gzip \n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -H 'Content-Encoding: gzip' -F \"file=@.gz\" 'https://{tank-base-url}/api/v2/scripts/upload'\n\n" + + "Notes: \n\n " + + " - This endpoint only accepts XML script file recorded and produced by the Tank Proxy Package (see Tools tab in Tank)\n\n" + + " - Both script name and script id are optional parameters \n\n" + + " - Passing in an existing Tank Script ID will overwrite the existing script in Tank, but will otherwise create a new Tank script", summary = "Upload script to Tank") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Successfully uploaded script file to Tank", content = @Content), + @ApiResponse(responseCode = "400", description = "Script file could not be uploaded", content = @Content) + }) + public ResponseEntity> uploadScript(@RequestHeader(value = HttpHeaders.CONTENT_ENCODING, required = false) @Parameter(description = "Content-Encoding", required = false) String contentEncoding, + @RequestParam(required = false) @Parameter(description = "Script Name", required = false) String name, + @RequestParam(required = false) @Parameter(description = "Existing Script ID (optional)", required = false) Integer id, + @RequestParam(value = "file", required = true) @Parameter(schema = @Schema(type = "string", format = "binary", description = "Script file")) MultipartFile file) throws IOException{ + Map response = scriptService.uploadProxyScript(name, id, contentEncoding, file); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } + + @RequestMapping(value = "/{scriptId}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) @ResponseStatus(HttpStatus.NO_CONTENT) @Operation(description = "Deletes a script by script ID", summary = "Delete a script") @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "No content (script delete successful)", content = @Content), @ApiResponse(responseCode = "404", description = "Script not found", content = @Content) }) public ResponseEntity deleteScript( - @PathVariable @Parameter(description = "Script ID", required = true) Integer scriptID) { - String response = scriptService.deleteScript(scriptID); + @PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) { + String response = scriptService.deleteScript(scriptId); if (Objects.equals(response, "")) { return new ResponseEntity<>(response, HttpStatus.NO_CONTENT); } @@ -104,18 +182,18 @@ public ResponseEntity deleteScript( @RequestMapping(value = "/external", method = RequestMethod.GET) @Operation(description = "Returns all external scripts descriptions", summary = "Get all external script descriptions") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found all external scripts"), - @ApiResponse(responseCode = "404", description = "All external scripts could not be found", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully found all external scripts descriptions"), + @ApiResponse(responseCode = "404", description = "All external scripts descriptions could not be found", content = @Content) }) public ResponseEntity getExternalScripts() { return new ResponseEntity<>(scriptService.getExternalScripts(), HttpStatus.OK); } - @RequestMapping(value = "/external/{externalScriptId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_XML_VALUE }) - @Operation(description = "Returns an external script by external script ID", summary = "Get a specific external script") + @RequestMapping(value = "/external/{externalScriptId}", method = RequestMethod.GET) + @Operation(description = "Returns an external script description by external script ID", summary = "Get a specific external script description") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found external script"), - @ApiResponse(responseCode = "404", description = "External script could not be found", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully found external script description"), + @ApiResponse(responseCode = "404", description = "External script description could not be found", content = @Content) }) public ResponseEntity getExternalScript(@PathVariable @Parameter(description = "External Script ID", required = true) Integer externalScriptId) { ExternalScriptTO script = scriptService.getExternalScript(externalScriptId); @@ -132,7 +210,7 @@ public ResponseEntity getExternalScript(@PathVariable @Paramet @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) }) public ResponseEntity createExternalScript( - @RequestBody @Parameter(description = "Script JSON request payload", required = true) ExternalScriptTO script) { + @RequestBody @Parameter(description = "External Script JSON request payload", required = true) ExternalScriptTO script) { ExternalScriptTO savedScript = scriptService.createExternalScript(script); URI location = ServletUriComponentsBuilder.fromCurrentRequest().scheme("https").path("/{id}").buildAndExpand(savedScript.getId()).toUri(); HttpHeaders responseHeaders = new HttpHeaders(); @@ -140,6 +218,29 @@ public ResponseEntity createExternalScript( return new ResponseEntity<>(savedScript, responseHeaders, HttpStatus.CREATED); } + @RequestMapping(value = "/external/download/{externalScriptId}", method = RequestMethod.GET) + @Operation(description = "Downloads the Tank XML file for an external script with the corresponding external script ID", summary = "Download an external script") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully downloaded the Tank XML external script file", content = @Content), + @ApiResponse(responseCode = "404", description = "Tank XML external script file could not be found", content = @Content) + }) + public ResponseEntity downloadExternalScript(@PathVariable @Parameter(description = "External Script ID", required = true) Integer externalScriptId) throws IOException { + Map response = scriptService.downloadExternalScript(externalScriptId); + 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 = "/external/{externalScriptId}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) @ResponseStatus(HttpStatus.NO_CONTENT) @Operation(description = "Deletes a external script by external script ID", summary = "Delete a external script") 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 006000430..30f6f7bfc 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 @@ -12,9 +12,16 @@ import org.apache.logging.log4j.LogManager; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartException; +import org.springframework.web.multipart.support.MissingServletRequestPartException; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +import javax.servlet.http.HttpServletRequest; @ResponseBody @ControllerAdvice @@ -42,6 +49,21 @@ public SimpleErrorResponse handleResourceDeleteException(GenericServiceDeleteExc return genericErrorResponse(HttpStatus.NOT_FOUND, "Resource could not be deleted: " + e.getResource(), e); } + @ExceptionHandler(MultipartException.class) + public ResponseEntity handleFileException(HttpServletRequest request, Throwable ex) { + return new ResponseEntity<>("File upload error: incorrect request or missing file parameter", HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(MissingServletRequestPartException.class) + public ResponseEntity handleMissingServletRequestPart(HttpServletRequest request, Throwable ex) { + return new ResponseEntity<>("File upload error: incorrect request or missing file parameter", HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + public ResponseEntity handleHttpMessageNotReadable(HttpServletRequest request, Throwable ex) { + return new ResponseEntity<>("Incorrect request body", HttpStatus.BAD_REQUEST); + } + @ExceptionHandler public SimpleErrorResponse handleClientException(ClientException e) { return genericErrorResponse(HttpStatus.valueOf(e.getStatusCode()), e.getErrorMessage(), e); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/RestRequestExceptionHandler.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/RestRequestExceptionHandler.java deleted file mode 100644 index f1aaf4512..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/RestRequestExceptionHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.intuit.tank.rest.mvc.rest.controllers.errors; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.context.request.WebRequest; -import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; - -@ControllerAdvice -public class RestRequestExceptionHandler extends ResponseEntityExceptionHandler { - - @Override - protected ResponseEntity handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { - return new ResponseEntity<>("Incorrect request body", HttpStatus.BAD_REQUEST); - } -} 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 ad1e50f0c..1e4f2d303 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 @@ -7,13 +7,18 @@ */ package com.intuit.tank.rest.mvc.rest.services.datafiles; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceDeleteException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptorContainer; +import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import java.io.IOException; +import java.util.Map; + public interface DataFileServiceV2 { /** @@ -35,6 +40,19 @@ public interface DataFileServiceV2 { */ public DataFileDescriptor getDatafile(Integer datafileId); + /** + * Downloads a specific datafile by datafile ID + * + * @param datafileId + * datafile ID corresponding to datafile + * + * @throws GenericServiceResourceNotFoundException + * if there are any errors downloading datafile + * + * @return datafile file + */ + public Map downloadDatafile(Integer datafileId); + /** * Returns datafile content * @param datafileId @@ -57,6 +75,26 @@ public interface DataFileServiceV2 { */ public DataFileDescriptorContainer getDatafiles(); + + /** + * Upload datafile to Tank + * + * @param datafileId + * existing datafile's datafileId to overwrite with new datafile + * + * @param contentEncoding + * content encoding of datafile (checks for gzip file) + * + * @param file + * datafile to be uploaded + * + * @throws GenericServiceCreateOrUpdateException + * if there are errors uploading datafile + * + * @return datafileId with upload status JSON payload + */ + public Map uploadDatafile(Integer datafileId, String contentEncoding, MultipartFile file) throws IOException; + /** * Deletes a datafile associated with datafile ID * 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 8dd32ad63..eacd79b83 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 @@ -9,6 +9,7 @@ import com.intuit.tank.dao.DataFileDao; import com.intuit.tank.project.DataFile; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceDeleteException; import com.intuit.tank.rest.mvc.rest.util.DataFileServiceUtil; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; @@ -20,18 +21,20 @@ import com.intuit.tank.util.DataFileUtil; import com.intuit.tank.vm.settings.TankConfig; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; +import java.io.*; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import java.util.zip.GZIPInputStream; @Service public class DataFileServiceV2Impl implements DataFileServiceV2 { @@ -117,6 +120,65 @@ private StreamingResponseBody getStreamingOutput(final Integer offset, final Int }; } + public Map downloadDatafile(Integer datafileId){ + Map payload = new HashMap(); + DataFileDao dataFileDao = new DataFileDao(); + DataFile dataFile = dataFileDao.findById(datafileId); + if (dataFile == null){ + return null; + } else { + StreamingResponseBody streamingOutput = getStreamingOutput(0, -1, dataFile); + String filename = dataFile.getPath(); + payload.put(filename, streamingOutput); + return payload; + } + } + + @Override + public Map uploadDatafile(Integer datafileId, String contentEncoding, MultipartFile file) throws IOException { + 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 { + DataFileDao dao = new DataFileDao(); + DataFile dataFile = dao.findById(datafileId); + if (dataFile == null){ + dataFile = new DataFile(); + dataFile.setCreator("System"); + dataFile.setId(0); + } else { + payload.put("message", "Datafile with datafile ID " + datafileId + " overwritten with new datafile"); + } + + String newFilename = file.getOriginalFilename().replace(".gz", ""); + dataFile.setPath(newFilename); + dataFile.setFileName(newFilename); + + dao.storeDataFile(dataFile, decompressed); + + if (datafileId.equals(0)) { + payload.put("message", "Datafile with new datafile ID " + dataFile.getId() + " has been uploaded"); + } else { + if (!payload.containsKey("message")) { + payload.put("message", "Existing dataFile with dataFile ID " + datafileId + " could not be found, created new datafile " + dataFile.getId()); + } + } + payload.put("datafileId", Integer.toString(dataFile.getId())); + } 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; + } + + @Override public String deleteDatafile(Integer datafileId){ try { 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 9fe1c60dc..935109e92 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 @@ -13,8 +13,14 @@ import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescription; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +import java.io.IOException; +import java.util.Map; public interface ScriptServiceV2 { @@ -39,16 +45,16 @@ public interface ScriptServiceV2 { public ScriptTO createScript(ScriptTO scriptTo); /** - * Retrieves a specific script by script ID + * Retrieves a specific script description by script ID * @param scriptId * script ID corresponding to script * * @throws GenericServiceResourceNotFoundException - * if there are any errors returning script + * if there are any errors returning script description * - * @return script JSON response + * @return script description JSON response */ - public ScriptTO getScript(Integer scriptId); + public ScriptDescription getScript(Integer scriptId); /** * Gets all scripts @@ -60,43 +66,94 @@ public interface ScriptServiceV2 { */ public ScriptDescriptionContainer getScripts(); + + /** + * Downloads a script's Tank XML file associated with scriptID + * + * @throws GenericServiceResourceNotFoundException + * if there are errors downloading the script + * + * @param scriptId + * scriptID for script to be downloaded + * + * @return script Tank XML file + */ + public Map downloadScript(Integer scriptId); + + /** + * Downloads a script's Harness XML file associated with scriptID + * + * @throws GenericServiceResourceNotFoundException + * if there are errors downloading script harness + * + * @param scriptId + * scriptID for script harness to be downloaded + * + * @return script harness XML file + */ + public Map downloadHarnessScript(Integer scriptId); + + + /** + * Upload external script recorded from Tank Proxy Package + * + * @param name + * name to assign to new or updated Tank script + * + * @param scriptId + * existing script's scriptID to overwrite with new script content + * + * @param contentEncoding + * content encoding of file (checks for gzip file) + * + * @param file + * script XML file to be uploaded + * + * @throws GenericServiceCreateOrUpdateException + * if there are errors uploading script + * + * @return scriptId with upload status JSON payload + */ + public Map uploadProxyScript(String name, Integer scriptId, String contentEncoding, MultipartFile file) throws IOException; + + /** * Deletes a script associated with scriptID * * @throws GenericServiceDeleteException * if there are errors deleting the script * - * @param scriptID + * @param scriptId * scriptID for script to be deleted * * @return string confirmation of script deletion */ - public String deleteScript(Integer scriptID); + public String deleteScript(Integer scriptId); // External Scripts /** - * Get all external scripts + * Get all external script descriptions * * @throws GenericServiceResourceNotFoundException * if there are errors returning all external scripts * - * @return list of external scripts + * @return list of external script descriptions */ public ExternalScriptContainer getExternalScripts(); /** - * Gets a specific external script by ID + * Gets a specific external script description by ID * * @param externalScriptId * id for external script * * @throws GenericServiceResourceNotFoundException - * if there are errors returning the external script + * if there are errors returning the external script description * - * @return External Script JSON response + * @return External Script description JSON response * */ public ExternalScriptTO getExternalScript(Integer externalScriptId); @@ -114,6 +171,20 @@ public interface ScriptServiceV2 { public ExternalScriptTO createExternalScript(ExternalScriptTO ExternalScriptRequest); + /** + * Downloads an external script's Tank XML file corresponding with external scriptsID + * + * @throws GenericServiceResourceNotFoundException + * if there are errors downloading external script + * + * @param externalScriptId + * external scriptID for external script to be downloaded + * + * @return external script file + */ + public Map downloadExternalScript(Integer externalScriptId); + + /** * Deletes an External Script * 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 1ca259eea..660807455 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 @@ -9,24 +9,49 @@ import com.intuit.tank.dao.ScriptDao; import com.intuit.tank.dao.ExternalScriptDao; +import com.intuit.tank.harness.data.HDWorkload; +import com.intuit.tank.project.BaseEntity; import com.intuit.tank.project.Script; import com.intuit.tank.project.ExternalScript; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceDeleteException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.models.scripts.*; +import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptServiceUtil; +import com.intuit.tank.script.processor.ScriptProcessor; +import com.intuit.tank.service.impl.v1.automation.MessageSender; +import com.intuit.tank.service.util.ServletInjector; +import com.intuit.tank.transform.scriptGenerator.ConverterUtil; +import com.intuit.tank.vm.settings.ModifiedEntityMessage; +import com.intuit.tank.vm.settings.ModificationType; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import java.util.zip.GZIPInputStream; +import javax.servlet.ServletContext; @Service public class ScriptServiceV2Impl implements ScriptServiceV2 { + @Autowired + private ServletContext servletContext; + private static final Logger LOGGER = LogManager.getLogger(ScriptServiceV2Impl.class); @Override @@ -50,16 +75,16 @@ public ScriptTO createScript(ScriptTO scriptTo) { } @Override - public ScriptTO getScript(Integer scriptId) { + public ScriptDescription getScript(Integer scriptId) { try { ScriptDao dao = new ScriptDao(); Script script = dao.findById(scriptId); if (script != null) { - return ScriptServiceUtil.scriptToTransferObject(script); + return ScriptServiceUtil.scriptToScriptDescription(script); } return null; } catch (Exception e) { - LOGGER.error("Error returning script: " + e.getMessage(), e); + LOGGER.error("Error returning script description: " + e.getMessage(), e); throw new GenericServiceResourceNotFoundException("scripts", "script", e); } } @@ -77,6 +102,50 @@ public ScriptDescriptionContainer getScripts() { } } + @Override + public Map downloadScript(Integer scriptId){ + try { + StreamingResponseBody streamingResponse; + Map payload = new HashMap(); + ScriptDao dao = new ScriptDao(); + final Script script = dao.findById(scriptId); + if (script == null) { + return null; + } else { + String filename = script.getName() + "_TS.xml"; + final ScriptTO scriptTO = ScriptServiceUtil.scriptToTransferObject(script); + streamingResponse = ResponseUtil.getXMLStream(scriptTO); + payload.put(filename, streamingResponse); + return payload; + } + } catch (Exception e) { + LOGGER.error("Error downloading Tank XML script file: " + e.getMessage(), e); + throw new GenericServiceResourceNotFoundException("scripts", "Tank XML script file", e); + } + } + + @Override + public Map downloadHarnessScript(Integer scriptId){ + try { + StreamingResponseBody streamingResponse; + Map payload = new HashMap(); + ScriptDao dao = new ScriptDao(); + final Script script = dao.findById(scriptId); + if (script == null) { + return null; + } else { + String filename = script.getName() + "_H.xml"; + final HDWorkload hdWorkload = ConverterUtil.convertScriptToHdWorkload(script); + streamingResponse = ResponseUtil.getXMLStream(hdWorkload); + payload.put(filename, streamingResponse); + return payload; + } + } catch (Exception e) { + LOGGER.error("Error downloading Tank Harness script file: " + e.getMessage(), e); + throw new GenericServiceResourceNotFoundException("scripts", "Tank Harness script file", e); + } + } + @Override public String deleteScript(Integer scriptId) { try { @@ -142,6 +211,82 @@ public ExternalScriptTO createExternalScript(ExternalScriptTO ExternalScriptRequ } } + @Override + public Map downloadExternalScript(Integer externalScriptId){ + try { + StreamingResponseBody streamingResponse; + Map payload = new HashMap(); + ExternalScriptDao dao = new ExternalScriptDao(); + final ExternalScript script = dao.findById(externalScriptId); + if (script == null) { + return null; + } else { + String filename = script.getName() + "_ETS.xml"; + final ExternalScriptTO externalScriptTO = ScriptServiceUtil.externalScriptToTO(script); + streamingResponse = ResponseUtil.getXMLStream(externalScriptTO); + payload.put(filename, streamingResponse); + return payload; + } + } catch (Exception e) { + LOGGER.error("Error downloading Tank XML external script file: " + e.getMessage(), e); + throw new GenericServiceResourceNotFoundException("scripts", "Tank XML external script file", e); + } + } + + @Override + public Map uploadProxyScript(String name, Integer scriptId, String contentEncoding, MultipartFile file) throws IOException { + Map payload = new HashMap<>(); + InputStream fileInputStream = file.getInputStream(); + scriptId = scriptId == null ? 0 : scriptId; + contentEncoding = contentEncoding == null ? "" : contentEncoding; + try { + Script script = new ScriptDao().findById(scriptId); + if (script == null){ + script = new Script(); + script.setName("New"); + script.setCreator("System"); + } else { + payload.put("message", "Script with script ID " + scriptId + " overwritten with new script content"); + } + + ScriptProcessor scriptProcessor = new ServletInjector().getManagedBean(servletContext, + ScriptProcessor.class); + + scriptProcessor.setScript(script); + if (StringUtils.isNotEmpty(name)) { + script.setName(name); + } + + BufferedReader bufferedReader = StringUtils.equalsIgnoreCase(contentEncoding, "gzip") ? + new BufferedReader(new InputStreamReader(new GZIPInputStream(fileInputStream))) : + new BufferedReader(new InputStreamReader(fileInputStream)); + scriptProcessor.getScriptSteps(bufferedReader, new ArrayList<>()); + script = new ScriptDao().saveOrUpdate(script); + sendMsg(script, ModificationType.UPDATE); + if (scriptId.equals(0)) { + payload.put("message", "Script with new script ID " + script.getId() + " has been uploaded"); + } else { + if (!payload.containsKey("message")) { + payload.put("message", "Existing script with script ID " + scriptId + " could not be found, created new script " + script.getId()); + } + } + payload.put("scriptId", Integer.toString(script.getId())); + } catch (Exception e) { + LOGGER.error("Error uploading script file: " + e.getMessage(), e); + throw new GenericServiceCreateOrUpdateException("scripts", "new script via script upload", e); + } finally { + try { + fileInputStream.close(); + } catch (IOException e) {} + } + return payload; + } + + private void sendMsg(BaseEntity entity, ModificationType type) { + MessageSender sender = new ServletInjector().getManagedBean(servletContext, MessageSender.class); + sender.sendEvent(new ModifiedEntityMessage(entity.getClass(), entity.getId(), type)); + } + @Override public String deleteExternalScript(Integer externalScriptId) { ExternalScriptDao dao = new ExternalScriptDao(); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java index 992be4d8a..c4ed0f9a8 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java @@ -34,11 +34,16 @@ public static DataFileDescriptor dataFileToDescriptor(DataFile dataFile) { ret.setModified(dataFile.getModified()); ret.setCreator(dataFile.getCreator()); ret.setName(dataFile.getPath()); -// ret.setDataUrl(getRelativeDataUrl(dataFile.getId())); TODO + ret.setDataUrl(getRelativeDataUrl(dataFile.getId())); ret.setComments(dataFile.getComments()); return ret; } + private static String getRelativeDataUrl(int id) { + String url = config.getControllerBase() + "/api/v2/datafiles/content?id={id}"; + return url.replace("{id}", Integer.toString(id)); + } + /** * @param dao * @param to the descriptor to convert diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ResponseUtil.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ResponseUtil.java index 0ccdc3a91..b25a9ae69 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ResponseUtil.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ResponseUtil.java @@ -12,16 +12,15 @@ import com.intuit.tank.harness.data.HDWorkload; import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.Workload; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; import com.intuit.tank.transform.scriptGenerator.ConverterUtil; import com.amazonaws.xray.AWSXRay; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.CacheControl; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; @@ -34,17 +33,17 @@ private ResponseUtil() { // empty private constructor to implement util pattern } - public static StreamingOutput getXMLStream(Object toMarshall) { + public static StreamingResponseBody getXMLStream(Object toMarshall) { return (OutputStream outputStream) -> { AWSXRay.beginSubsegment("JAXB.Marshal." + toMarshall.getClass().getSimpleName()); try { - JAXBContext ctx = JAXBContext.newInstance(toMarshall.getClass().getPackage().getName()); + JAXBContext ctx = JAXBContext.newInstance(toMarshall.getClass()); Marshaller marshaller = ctx.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(toMarshall, outputStream); } catch (JAXBException e) { LOG.error("Error Marshalling XML to Stream: " + e.toString(), e); - throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); + throw new GenericServiceResourceNotFoundException("scripts", "script file", e); } finally { AWSXRay.endSubsegment(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java deleted file mode 100644 index 0d72083c4..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.util; - -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.servlet.ServletContext; - -public class ServletInjector { - - private BeanManager getBeanManager(ServletContext servletContext) { - return (BeanManager) servletContext - .getAttribute("org.jboss.weld.environment.servlet.javax.enterprise.inject.spi.BeanManager"); - } - - @SuppressWarnings({ "unchecked" }) - public T getManagedBean(ServletContext servletContext, Class beanClass) { - BeanManager beanManager = getBeanManager(servletContext); - Bean bean = beanManager.getBeans(beanClass).iterator().next(); - CreationalContext cc = beanManager.createCreationalContext(bean); - return (T) beanManager.getReference(bean, beanClass, cc); - } -} diff --git a/rest-mvc/src/main/resources/application.yml b/rest-mvc/src/main/resources/application.yml index 1a4b09564..8d7e4c8d0 100644 --- a/rest-mvc/src/main/resources/application.yml +++ b/rest-mvc/src/main/resources/application.yml @@ -31,6 +31,10 @@ server: cookie: secure: true http-only: true + multipart: + enabled: true + max-file-size: 200MB + max-request-size: 200MB tomcat: accesslog: request-attributes-enabled: true diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileControllerTest.java index 6e0e35dee..0534b772e 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileControllerTest.java @@ -10,9 +10,11 @@ import com.intuit.tank.project.DataFile; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptorContainer; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; import com.intuit.tank.rest.mvc.rest.services.datafiles.DataFileServiceV2; import com.intuit.tank.rest.mvc.rest.util.DataFileServiceUtil; +import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -23,6 +25,7 @@ import static org.mockito.Mockito.when; import org.springframework.http.ResponseEntity; +import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; @@ -32,9 +35,7 @@ import java.io.IOException; import java.io.ByteArrayOutputStream; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; public class DataFileControllerTest { @@ -115,6 +116,37 @@ public void testGetDatafileContent() throws IOException { verify(datafileService).getDatafileContent(2, 5, 10); } + @Test + public void testDownloadDatafile() throws IOException { + Map payload = new HashMap(); + File testCSV = new File("src/test/resources/test.csv"); + StreamingResponseBody responseBody = outputStream -> { + Files.copy(testCSV.toPath(), outputStream); + }; + String filename = "test.csv"; + payload.put(filename, responseBody); + when(datafileService.downloadDatafile(4)).thenReturn(payload); + ResponseEntity result = datafileController.downloadDatafile(4); + assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); + assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); + assertEquals(200, result.getStatusCodeValue()); + verify(datafileService).downloadDatafile(4); + } + + @Test + public void testUploadDatafile() throws IOException { + Map payload = new HashMap<>(); + payload.put("datafileId", "6"); + payload.put("message", "Datafile with new datafile ID 6 has been uploaded"); + when(datafileService.uploadDatafile(0, "gzip", null)).thenReturn(payload); + ResponseEntity> result = datafileController.uploadDatafile("gzip", 0, null); + Map response = result.getBody(); + assertEquals("6", response.get("datafileId")); + assertTrue(response.get("message").contains("uploaded")); + assertEquals(201, result.getStatusCodeValue()); + verify(datafileService).uploadDatafile(0, "gzip", null); + } + @Test public void testDeleteDatafile() { when(datafileService.deleteDatafile(1)).thenReturn(""); diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptControllerTest.java index d2ae13e2c..d77dd84fa 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptControllerTest.java @@ -15,6 +15,7 @@ import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescription; import com.intuit.tank.rest.mvc.rest.services.scripts.ScriptServiceV2; +import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptServiceUtil; import org.junit.jupiter.api.BeforeEach; @@ -27,13 +28,15 @@ import static org.mockito.Mockito.when; import org.springframework.http.ResponseEntity; +import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; -import java.util.List; +import java.io.IOException; +import java.util.*; import java.util.stream.Collectors; public class ScriptControllerTest { @@ -86,15 +89,15 @@ public void testGetScript() { Script script = new Script(); script.setName("testName"); script.setProductName("testProductName"); - when(scriptService.getScript(2)).thenReturn(ScriptServiceUtil.scriptToTransferObject(script)); - ResponseEntity result = scriptController.getScript(2); + when(scriptService.getScript(2)).thenReturn(ScriptServiceUtil.scriptToScriptDescription(script)); + ResponseEntity result = scriptController.getScript(2); assertEquals("testName", result.getBody().getName()); assertEquals("testProductName", result.getBody().getProductName()); assertEquals(200, result.getStatusCodeValue()); verify(scriptService).getScript(2); when(scriptService.getScript(2)).thenReturn(null); - ResponseEntity notFound = scriptController.getScript(2); + ResponseEntity notFound = scriptController.getScript(2); assertEquals(404, notFound.getStatusCodeValue()); } @@ -115,6 +118,58 @@ public void testCreateScript() { verify(scriptService).createScript(payload); } + @Test + public void testDownloadScript() throws IOException { + Map payload = new HashMap(); + ScriptTO scriptTO = new ScriptTO(); + scriptTO.setId(4); + scriptTO.setCreator("Test"); + scriptTO.setName("testName"); + scriptTO.setRuntime(3); + StreamingResponseBody streamingResponse = ResponseUtil.getXMLStream(scriptTO); + String filename = "test_TS.xml"; + payload.put(filename, streamingResponse); + when(scriptService.downloadScript(4)).thenReturn(payload); + ResponseEntity result = scriptController.downloadScript(4); + assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); + assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); + assertEquals(200, result.getStatusCodeValue()); + verify(scriptService).downloadScript(4); + } + + @Test + public void testDownloadHarnessScript() throws IOException { + Map payload = new HashMap(); + ScriptTO scriptTO = new ScriptTO(); + scriptTO.setId(4); + scriptTO.setCreator("Test"); + scriptTO.setName("testName"); + scriptTO.setRuntime(3); + StreamingResponseBody streamingResponse = ResponseUtil.getXMLStream(scriptTO); + String filename = "test_H.xml"; + payload.put(filename, streamingResponse); + when(scriptService.downloadHarnessScript(4)).thenReturn(payload); + ResponseEntity result = scriptController.downloadHarnessScript(4); + assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); + assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); + assertEquals(200, result.getStatusCodeValue()); + verify(scriptService).downloadHarnessScript(4); + } + + @Test + public void testUploadScript() throws IOException { + Map payload = new HashMap<>(); + payload.put("scriptId", "7"); + payload.put("message", "Script with new script ID 7 has been uploaded"); + when(scriptService.uploadProxyScript("testName", 0, "gzip", null)).thenReturn(payload); + ResponseEntity> result = scriptController.uploadScript("gzip", "testName", 0, null); + Map response = result.getBody(); + assertEquals("7", response.get("scriptId")); + assertTrue(response.get("message").contains("uploaded")); + assertEquals(201, result.getStatusCodeValue()); + verify(scriptService).uploadProxyScript("testName", 0, "gzip", null); + } + @Test public void testDeleteScript() { when(scriptService.deleteScript(1)).thenReturn(""); @@ -186,6 +241,24 @@ public void testCreateExternalScript() { verify(scriptService).createExternalScript(payload); } + @Test + public void testDownloadExternalScript() throws IOException { + Map payload = new HashMap(); + ExternalScriptTO externalScriptTO = new ExternalScriptTO(); + externalScriptTO.setId(5); + externalScriptTO.setCreator("Test"); + externalScriptTO.setName("testExternalName"); + StreamingResponseBody streamingResponse = ResponseUtil.getXMLStream(externalScriptTO); + String filename = "test_ETS.xml"; + payload.put(filename, streamingResponse); + when(scriptService.downloadExternalScript(5)).thenReturn(payload); + ResponseEntity result = scriptController.downloadExternalScript(5); + assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); + assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); + assertEquals(200, result.getStatusCodeValue()); + verify(scriptService).downloadExternalScript(5); + } + @Test public void testDeleteExternalScript() { when(scriptService.deleteExternalScript(2)).thenReturn(""); diff --git a/web/web_ui/src/main/webapp/WEB-INF/web.xml b/web/web_ui/src/main/webapp/WEB-INF/web.xml index 8f605818d..d34f08a97 100644 --- a/web/web_ui/src/main/webapp/WEB-INF/web.xml +++ b/web/web_ui/src/main/webapp/WEB-INF/web.xml @@ -71,6 +71,12 @@ 0 true + + /tmp + 200000000 + 200000000 + 1048576 + rest-mvc From 2fe9b7e69ac2882c7ee75b74005803f0a19f04d8 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Sun, 26 Mar 2023 17:54:22 -0700 Subject: [PATCH 05/73] Revert "feat: [SRE-26521] upload/download for scripts/datafiles" This reverts commit 66d2ca40b51d0172060c5f040a8cc447f5cf7b93. --- .../rest/controllers/DataFileController.java | 48 ------ .../rest/controllers/ScriptController.java | 135 ++-------------- .../errors/GenericExceptionHandler.java | 22 --- .../errors/RestRequestExceptionHandler.java | 18 +++ .../services/datafiles/DataFileServiceV2.java | 38 ----- .../datafiles/DataFileServiceV2Impl.java | 70 +------- .../services/scripts/ScriptServiceV2.java | 93 ++--------- .../services/scripts/ScriptServiceV2Impl.java | 151 +----------------- .../mvc/rest/util/DataFileServiceUtil.java | 7 +- .../tank/rest/mvc/rest/util/ResponseUtil.java | 11 +- .../rest/mvc/rest/util/ServletInjector.java | 29 ++++ rest-mvc/src/main/resources/application.yml | 4 - .../controllers/DataFileControllerTest.java | 38 +---- .../controllers/ScriptControllerTest.java | 83 +--------- web/web_ui/src/main/webapp/WEB-INF/web.xml | 6 - 15 files changed, 97 insertions(+), 656 deletions(-) create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/RestRequestExceptionHandler.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java 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..7d57d12ce 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 @@ -14,7 +14,6 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; @@ -30,7 +29,6 @@ import javax.annotation.Resource; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.Map; import java.util.Objects; @RestController @@ -91,52 +89,6 @@ public ResponseEntity getDatafileContent(@RequestParam(required = true) return ResponseEntity.notFound().build(); } - @RequestMapping(value = "/download/{datafileId}", method = RequestMethod.GET) - @Operation(description = "Downloads a datafile with the corresponding datafile ID", summary = "Download a datafile") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully downloaded the datafile", content = @Content), - @ApiResponse(responseCode = "404", description = "Datafile could not be found", content = @Content) - }) - public ResponseEntity downloadDatafile(@PathVariable @Parameter(description = "Datafile ID", required = true) Integer datafileId) throws IOException { - Map response = dataFileService.downloadDatafile(datafileId); - 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 = "/upload", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) - @Operation(description = "Uploads a datafile to Tank (supports gzip files) \n\n " + - "Examples: \n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/datafiles/upload'\n\n" + - "\n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/datafiles/upload?id='\n\n" + - "\n\n" + - " gzip \n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -H 'Content-Encoding: gzip' -F \"file=@.gz\" 'https://{tank-base-url}/api/v2/datafiles/upload'\n\n" + - "Notes: \n\n " + - " - Datafile id is an optional parameter \n\n" + - " - Passing in an existing Tank Datafile ID will overwrite the existing datafile in Tank, but will otherwise create a new datafile", summary = "Upload datafile to Tank") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Successfully uploaded datafile", content = @Content), - @ApiResponse(responseCode = "400", description = "Datafile could not be uploaded", content = @Content) - }) - public ResponseEntity> uploadDatafile(@RequestHeader(value = HttpHeaders.CONTENT_ENCODING, required = false) @Parameter(description = "Content-Encoding", required = false) String contentEncoding, - @RequestParam(required = false) @Parameter(description = "Existing Datafile ID (optional)", required = false) Integer id, - @RequestParam(value = "file", required = true) @Parameter(schema = @Schema(type = "string", format = "binary", description = "Datafile file")) MultipartFile file) throws IOException{ - Map response = dataFileService.uploadDatafile(id, contentEncoding, file); - return new ResponseEntity<>(response, HttpStatus.CREATED); - } - @RequestMapping(value = "/{datafileID}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) @ResponseStatus(HttpStatus.NO_CONTENT) @Operation(description = "Deletes a specific datafile by datafile ID", summary = "Delete a datafile") 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..b762b705c 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 @@ -9,31 +9,24 @@ import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; -import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescription; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; import com.intuit.tank.rest.mvc.rest.services.scripts.ScriptServiceV2; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import java.io.*; import java.net.URI; -import java.util.Map; import java.util.Objects; import javax.annotation.Resource; @@ -54,8 +47,8 @@ public ResponseEntity ping() { } @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found all script descriptions"), - @ApiResponse(responseCode = "404", description = "All scripts descriptions could not be found", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully found all scripts"), + @ApiResponse(responseCode = "404", description = "All scripts could not be found", content = @Content) }) @RequestMapping(method = RequestMethod.GET) @Operation(description = "Returns all script descriptions", summary = "Get all script descriptions") @@ -63,14 +56,14 @@ public ResponseEntity getScripts() { return new ResponseEntity<>(scriptService.getScripts(), HttpStatus.OK); } - @RequestMapping(value = "/{scriptId}", method = RequestMethod.GET) + @RequestMapping(value = "/{scriptId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_XML_VALUE }) @Operation(description = "Returns a specific script description by script ID", summary = "Get a specific script description") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found script description"), - @ApiResponse(responseCode = "404", description = "Script description could not be found", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully found script"), + @ApiResponse(responseCode = "404", description = "Script could not be found", content = @Content) }) - public ResponseEntity getScript(@PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) { - ScriptDescription script = scriptService.getScript(scriptId); + public ResponseEntity getScript(@PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) { + ScriptTO script = scriptService.getScript(scriptId); if (script != null){ return new ResponseEntity<>(script, HttpStatus.OK); } @@ -92,85 +85,14 @@ public ResponseEntity createScript( return new ResponseEntity<>(savedScript, responseHeaders, HttpStatus.CREATED); } - @RequestMapping(value = "/download/{scriptId}", method = RequestMethod.GET) - @Operation(description = "Downloads the Tank XML file for a script with the corresponding script ID", summary = "Download the Tank XML script file") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully downloaded the Tank XML script file", content = @Content), - @ApiResponse(responseCode = "404", description = "Tank XML script file could not be found", content = @Content) - }) - public ResponseEntity downloadScript(@PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) throws IOException { - Map response = scriptService.downloadScript(scriptId); - 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 = "/harness/download/{scriptId}", method = RequestMethod.GET) - @Operation(description = "Downloads the Tank Harness file for a script with the corresponding script ID", summary = "Download the Tank Harness script file") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully downloaded the Tank Harness script file", content = @Content), - @ApiResponse(responseCode = "404", description = "Tank Harness script file could not be found", content = @Content) - }) - public ResponseEntity downloadHarnessScript(@PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) throws IOException { - Map response = scriptService.downloadHarnessScript(scriptId); - 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 = "/upload", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) - @Operation(description = "Uploads a script XML file output generated by the Tank Proxy Package (supports gzip files) \n\n " + - "Examples: \n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/scripts/upload' \n\n" + - "\n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/scripts/upload?id=&name='\n\n" + - "\n\n" + - " gzip \n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -H 'Content-Encoding: gzip' -F \"file=@.gz\" 'https://{tank-base-url}/api/v2/scripts/upload'\n\n" + - "Notes: \n\n " + - " - This endpoint only accepts XML script file recorded and produced by the Tank Proxy Package (see Tools tab in Tank)\n\n" + - " - Both script name and script id are optional parameters \n\n" + - " - Passing in an existing Tank Script ID will overwrite the existing script in Tank, but will otherwise create a new Tank script", summary = "Upload script to Tank") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Successfully uploaded script file to Tank", content = @Content), - @ApiResponse(responseCode = "400", description = "Script file could not be uploaded", content = @Content) - }) - public ResponseEntity> uploadScript(@RequestHeader(value = HttpHeaders.CONTENT_ENCODING, required = false) @Parameter(description = "Content-Encoding", required = false) String contentEncoding, - @RequestParam(required = false) @Parameter(description = "Script Name", required = false) String name, - @RequestParam(required = false) @Parameter(description = "Existing Script ID (optional)", required = false) Integer id, - @RequestParam(value = "file", required = true) @Parameter(schema = @Schema(type = "string", format = "binary", description = "Script file")) MultipartFile file) throws IOException{ - Map response = scriptService.uploadProxyScript(name, id, contentEncoding, file); - return new ResponseEntity<>(response, HttpStatus.CREATED); - } - - @RequestMapping(value = "/{scriptId}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) + @RequestMapping(value = "/{scriptID}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) @ResponseStatus(HttpStatus.NO_CONTENT) @Operation(description = "Deletes a script by script ID", summary = "Delete a script") @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "No content (script delete successful)", content = @Content), @ApiResponse(responseCode = "404", description = "Script not found", content = @Content) }) public ResponseEntity deleteScript( - @PathVariable @Parameter(description = "Script ID", required = true) Integer scriptId) { - String response = scriptService.deleteScript(scriptId); + @PathVariable @Parameter(description = "Script ID", required = true) Integer scriptID) { + String response = scriptService.deleteScript(scriptID); if (Objects.equals(response, "")) { return new ResponseEntity<>(response, HttpStatus.NO_CONTENT); } @@ -182,18 +104,18 @@ public ResponseEntity deleteScript( @RequestMapping(value = "/external", method = RequestMethod.GET) @Operation(description = "Returns all external scripts descriptions", summary = "Get all external script descriptions") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found all external scripts descriptions"), - @ApiResponse(responseCode = "404", description = "All external scripts descriptions could not be found", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully found all external scripts"), + @ApiResponse(responseCode = "404", description = "All external scripts could not be found", content = @Content) }) public ResponseEntity getExternalScripts() { return new ResponseEntity<>(scriptService.getExternalScripts(), HttpStatus.OK); } - @RequestMapping(value = "/external/{externalScriptId}", method = RequestMethod.GET) - @Operation(description = "Returns an external script description by external script ID", summary = "Get a specific external script description") + @RequestMapping(value = "/external/{externalScriptId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_XML_VALUE }) + @Operation(description = "Returns an external script by external script ID", summary = "Get a specific external script") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found external script description"), - @ApiResponse(responseCode = "404", description = "External script description could not be found", content = @Content) + @ApiResponse(responseCode = "200", description = "Successfully found external script"), + @ApiResponse(responseCode = "404", description = "External script could not be found", content = @Content) }) public ResponseEntity getExternalScript(@PathVariable @Parameter(description = "External Script ID", required = true) Integer externalScriptId) { ExternalScriptTO script = scriptService.getExternalScript(externalScriptId); @@ -210,7 +132,7 @@ public ResponseEntity getExternalScript(@PathVariable @Paramet @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) }) public ResponseEntity createExternalScript( - @RequestBody @Parameter(description = "External Script JSON request payload", required = true) ExternalScriptTO script) { + @RequestBody @Parameter(description = "Script JSON request payload", required = true) ExternalScriptTO script) { ExternalScriptTO savedScript = scriptService.createExternalScript(script); URI location = ServletUriComponentsBuilder.fromCurrentRequest().scheme("https").path("/{id}").buildAndExpand(savedScript.getId()).toUri(); HttpHeaders responseHeaders = new HttpHeaders(); @@ -218,29 +140,6 @@ public ResponseEntity createExternalScript( return new ResponseEntity<>(savedScript, responseHeaders, HttpStatus.CREATED); } - @RequestMapping(value = "/external/download/{externalScriptId}", method = RequestMethod.GET) - @Operation(description = "Downloads the Tank XML file for an external script with the corresponding external script ID", summary = "Download an external script") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully downloaded the Tank XML external script file", content = @Content), - @ApiResponse(responseCode = "404", description = "Tank XML external script file could not be found", content = @Content) - }) - public ResponseEntity downloadExternalScript(@PathVariable @Parameter(description = "External Script ID", required = true) Integer externalScriptId) throws IOException { - Map response = scriptService.downloadExternalScript(externalScriptId); - 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 = "/external/{externalScriptId}", method = RequestMethod.DELETE, produces = { MediaType.TEXT_PLAIN_VALUE }) @ResponseStatus(HttpStatus.NO_CONTENT) @Operation(description = "Deletes a external script by external script ID", summary = "Delete a external script") 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 30f6f7bfc..006000430 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 @@ -12,16 +12,9 @@ import org.apache.logging.log4j.LogManager; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.multipart.MultipartException; -import org.springframework.web.multipart.support.MissingServletRequestPartException; -import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; - -import javax.servlet.http.HttpServletRequest; @ResponseBody @ControllerAdvice @@ -49,21 +42,6 @@ public SimpleErrorResponse handleResourceDeleteException(GenericServiceDeleteExc return genericErrorResponse(HttpStatus.NOT_FOUND, "Resource could not be deleted: " + e.getResource(), e); } - @ExceptionHandler(MultipartException.class) - public ResponseEntity handleFileException(HttpServletRequest request, Throwable ex) { - return new ResponseEntity<>("File upload error: incorrect request or missing file parameter", HttpStatus.BAD_REQUEST); - } - - @ExceptionHandler(MissingServletRequestPartException.class) - public ResponseEntity handleMissingServletRequestPart(HttpServletRequest request, Throwable ex) { - return new ResponseEntity<>("File upload error: incorrect request or missing file parameter", HttpStatus.BAD_REQUEST); - } - - @ExceptionHandler(HttpMessageNotReadableException.class) - public ResponseEntity handleHttpMessageNotReadable(HttpServletRequest request, Throwable ex) { - return new ResponseEntity<>("Incorrect request body", HttpStatus.BAD_REQUEST); - } - @ExceptionHandler public SimpleErrorResponse handleClientException(ClientException e) { return genericErrorResponse(HttpStatus.valueOf(e.getStatusCode()), e.getErrorMessage(), e); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/RestRequestExceptionHandler.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/RestRequestExceptionHandler.java new file mode 100644 index 000000000..f1aaf4512 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/RestRequestExceptionHandler.java @@ -0,0 +1,18 @@ +package com.intuit.tank.rest.mvc.rest.controllers.errors; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@ControllerAdvice +public class RestRequestExceptionHandler extends ResponseEntityExceptionHandler { + + @Override + protected ResponseEntity handleHttpMessageNotReadable(HttpMessageNotReadableException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { + return new ResponseEntity<>("Incorrect request body", HttpStatus.BAD_REQUEST); + } +} 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..ad1e50f0c 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 @@ -7,18 +7,13 @@ */ package com.intuit.tank.rest.mvc.rest.services.datafiles; -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceDeleteException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptorContainer; -import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import java.io.IOException; -import java.util.Map; - public interface DataFileServiceV2 { /** @@ -40,19 +35,6 @@ public interface DataFileServiceV2 { */ public DataFileDescriptor getDatafile(Integer datafileId); - /** - * Downloads a specific datafile by datafile ID - * - * @param datafileId - * datafile ID corresponding to datafile - * - * @throws GenericServiceResourceNotFoundException - * if there are any errors downloading datafile - * - * @return datafile file - */ - public Map downloadDatafile(Integer datafileId); - /** * Returns datafile content * @param datafileId @@ -75,26 +57,6 @@ public interface DataFileServiceV2 { */ public DataFileDescriptorContainer getDatafiles(); - - /** - * Upload datafile to Tank - * - * @param datafileId - * existing datafile's datafileId to overwrite with new datafile - * - * @param contentEncoding - * content encoding of datafile (checks for gzip file) - * - * @param file - * datafile to be uploaded - * - * @throws GenericServiceCreateOrUpdateException - * if there are errors uploading datafile - * - * @return datafileId with upload status JSON payload - */ - public Map uploadDatafile(Integer datafileId, String contentEncoding, MultipartFile file) throws IOException; - /** * Deletes a datafile associated with datafile ID * 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..8dd32ad63 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 @@ -9,7 +9,6 @@ import com.intuit.tank.dao.DataFileDao; import com.intuit.tank.project.DataFile; -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceDeleteException; import com.intuit.tank.rest.mvc.rest.util.DataFileServiceUtil; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; @@ -21,20 +20,18 @@ import com.intuit.tank.util.DataFileUtil; import com.intuit.tank.vm.settings.TankConfig; -import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import java.io.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; import java.nio.charset.StandardCharsets; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; -import java.util.zip.GZIPInputStream; @Service public class DataFileServiceV2Impl implements DataFileServiceV2 { @@ -120,65 +117,6 @@ private StreamingResponseBody getStreamingOutput(final Integer offset, final Int }; } - public Map downloadDatafile(Integer datafileId){ - Map payload = new HashMap(); - DataFileDao dataFileDao = new DataFileDao(); - DataFile dataFile = dataFileDao.findById(datafileId); - if (dataFile == null){ - return null; - } else { - StreamingResponseBody streamingOutput = getStreamingOutput(0, -1, dataFile); - String filename = dataFile.getPath(); - payload.put(filename, streamingOutput); - return payload; - } - } - - @Override - public Map uploadDatafile(Integer datafileId, String contentEncoding, MultipartFile file) throws IOException { - 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 { - DataFileDao dao = new DataFileDao(); - DataFile dataFile = dao.findById(datafileId); - if (dataFile == null){ - dataFile = new DataFile(); - dataFile.setCreator("System"); - dataFile.setId(0); - } else { - payload.put("message", "Datafile with datafile ID " + datafileId + " overwritten with new datafile"); - } - - String newFilename = file.getOriginalFilename().replace(".gz", ""); - dataFile.setPath(newFilename); - dataFile.setFileName(newFilename); - - dao.storeDataFile(dataFile, decompressed); - - if (datafileId.equals(0)) { - payload.put("message", "Datafile with new datafile ID " + dataFile.getId() + " has been uploaded"); - } else { - if (!payload.containsKey("message")) { - payload.put("message", "Existing dataFile with dataFile ID " + datafileId + " could not be found, created new datafile " + dataFile.getId()); - } - } - payload.put("datafileId", Integer.toString(dataFile.getId())); - } 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; - } - - @Override public String deleteDatafile(Integer datafileId){ try { 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..9fe1c60dc 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 @@ -13,14 +13,8 @@ import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; -import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescription; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; - -import java.io.IOException; -import java.util.Map; public interface ScriptServiceV2 { @@ -45,16 +39,16 @@ public interface ScriptServiceV2 { public ScriptTO createScript(ScriptTO scriptTo); /** - * Retrieves a specific script description by script ID + * Retrieves a specific script by script ID * @param scriptId * script ID corresponding to script * * @throws GenericServiceResourceNotFoundException - * if there are any errors returning script description + * if there are any errors returning script * - * @return script description JSON response + * @return script JSON response */ - public ScriptDescription getScript(Integer scriptId); + public ScriptTO getScript(Integer scriptId); /** * Gets all scripts @@ -66,94 +60,43 @@ public interface ScriptServiceV2 { */ public ScriptDescriptionContainer getScripts(); - - /** - * Downloads a script's Tank XML file associated with scriptID - * - * @throws GenericServiceResourceNotFoundException - * if there are errors downloading the script - * - * @param scriptId - * scriptID for script to be downloaded - * - * @return script Tank XML file - */ - public Map downloadScript(Integer scriptId); - - /** - * Downloads a script's Harness XML file associated with scriptID - * - * @throws GenericServiceResourceNotFoundException - * if there are errors downloading script harness - * - * @param scriptId - * scriptID for script harness to be downloaded - * - * @return script harness XML file - */ - public Map downloadHarnessScript(Integer scriptId); - - - /** - * Upload external script recorded from Tank Proxy Package - * - * @param name - * name to assign to new or updated Tank script - * - * @param scriptId - * existing script's scriptID to overwrite with new script content - * - * @param contentEncoding - * content encoding of file (checks for gzip file) - * - * @param file - * script XML file to be uploaded - * - * @throws GenericServiceCreateOrUpdateException - * if there are errors uploading script - * - * @return scriptId with upload status JSON payload - */ - public Map uploadProxyScript(String name, Integer scriptId, String contentEncoding, MultipartFile file) throws IOException; - - /** * Deletes a script associated with scriptID * * @throws GenericServiceDeleteException * if there are errors deleting the script * - * @param scriptId + * @param scriptID * scriptID for script to be deleted * * @return string confirmation of script deletion */ - public String deleteScript(Integer scriptId); + public String deleteScript(Integer scriptID); // External Scripts /** - * Get all external script descriptions + * Get all external scripts * * @throws GenericServiceResourceNotFoundException * if there are errors returning all external scripts * - * @return list of external script descriptions + * @return list of external scripts */ public ExternalScriptContainer getExternalScripts(); /** - * Gets a specific external script description by ID + * Gets a specific external script by ID * * @param externalScriptId * id for external script * * @throws GenericServiceResourceNotFoundException - * if there are errors returning the external script description + * if there are errors returning the external script * - * @return External Script description JSON response + * @return External Script JSON response * */ public ExternalScriptTO getExternalScript(Integer externalScriptId); @@ -171,20 +114,6 @@ public interface ScriptServiceV2 { public ExternalScriptTO createExternalScript(ExternalScriptTO ExternalScriptRequest); - /** - * Downloads an external script's Tank XML file corresponding with external scriptsID - * - * @throws GenericServiceResourceNotFoundException - * if there are errors downloading external script - * - * @param externalScriptId - * external scriptID for external script to be downloaded - * - * @return external script file - */ - public Map downloadExternalScript(Integer externalScriptId); - - /** * Deletes an External Script * 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..1ca259eea 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 @@ -9,49 +9,24 @@ import com.intuit.tank.dao.ScriptDao; import com.intuit.tank.dao.ExternalScriptDao; -import com.intuit.tank.harness.data.HDWorkload; -import com.intuit.tank.project.BaseEntity; import com.intuit.tank.project.Script; import com.intuit.tank.project.ExternalScript; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceDeleteException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.models.scripts.*; -import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptServiceUtil; -import com.intuit.tank.script.processor.ScriptProcessor; -import com.intuit.tank.service.impl.v1.automation.MessageSender; -import com.intuit.tank.service.util.ServletInjector; -import com.intuit.tank.transform.scriptGenerator.ConverterUtil; -import com.intuit.tank.vm.settings.ModifiedEntityMessage; -import com.intuit.tank.vm.settings.ModificationType; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; -import java.util.zip.GZIPInputStream; -import javax.servlet.ServletContext; @Service public class ScriptServiceV2Impl implements ScriptServiceV2 { - @Autowired - private ServletContext servletContext; - private static final Logger LOGGER = LogManager.getLogger(ScriptServiceV2Impl.class); @Override @@ -75,16 +50,16 @@ public ScriptTO createScript(ScriptTO scriptTo) { } @Override - public ScriptDescription getScript(Integer scriptId) { + public ScriptTO getScript(Integer scriptId) { try { ScriptDao dao = new ScriptDao(); Script script = dao.findById(scriptId); if (script != null) { - return ScriptServiceUtil.scriptToScriptDescription(script); + return ScriptServiceUtil.scriptToTransferObject(script); } return null; } catch (Exception e) { - LOGGER.error("Error returning script description: " + e.getMessage(), e); + LOGGER.error("Error returning script: " + e.getMessage(), e); throw new GenericServiceResourceNotFoundException("scripts", "script", e); } } @@ -102,50 +77,6 @@ public ScriptDescriptionContainer getScripts() { } } - @Override - public Map downloadScript(Integer scriptId){ - try { - StreamingResponseBody streamingResponse; - Map payload = new HashMap(); - ScriptDao dao = new ScriptDao(); - final Script script = dao.findById(scriptId); - if (script == null) { - return null; - } else { - String filename = script.getName() + "_TS.xml"; - final ScriptTO scriptTO = ScriptServiceUtil.scriptToTransferObject(script); - streamingResponse = ResponseUtil.getXMLStream(scriptTO); - payload.put(filename, streamingResponse); - return payload; - } - } catch (Exception e) { - LOGGER.error("Error downloading Tank XML script file: " + e.getMessage(), e); - throw new GenericServiceResourceNotFoundException("scripts", "Tank XML script file", e); - } - } - - @Override - public Map downloadHarnessScript(Integer scriptId){ - try { - StreamingResponseBody streamingResponse; - Map payload = new HashMap(); - ScriptDao dao = new ScriptDao(); - final Script script = dao.findById(scriptId); - if (script == null) { - return null; - } else { - String filename = script.getName() + "_H.xml"; - final HDWorkload hdWorkload = ConverterUtil.convertScriptToHdWorkload(script); - streamingResponse = ResponseUtil.getXMLStream(hdWorkload); - payload.put(filename, streamingResponse); - return payload; - } - } catch (Exception e) { - LOGGER.error("Error downloading Tank Harness script file: " + e.getMessage(), e); - throw new GenericServiceResourceNotFoundException("scripts", "Tank Harness script file", e); - } - } - @Override public String deleteScript(Integer scriptId) { try { @@ -211,82 +142,6 @@ public ExternalScriptTO createExternalScript(ExternalScriptTO ExternalScriptRequ } } - @Override - public Map downloadExternalScript(Integer externalScriptId){ - try { - StreamingResponseBody streamingResponse; - Map payload = new HashMap(); - ExternalScriptDao dao = new ExternalScriptDao(); - final ExternalScript script = dao.findById(externalScriptId); - if (script == null) { - return null; - } else { - String filename = script.getName() + "_ETS.xml"; - final ExternalScriptTO externalScriptTO = ScriptServiceUtil.externalScriptToTO(script); - streamingResponse = ResponseUtil.getXMLStream(externalScriptTO); - payload.put(filename, streamingResponse); - return payload; - } - } catch (Exception e) { - LOGGER.error("Error downloading Tank XML external script file: " + e.getMessage(), e); - throw new GenericServiceResourceNotFoundException("scripts", "Tank XML external script file", e); - } - } - - @Override - public Map uploadProxyScript(String name, Integer scriptId, String contentEncoding, MultipartFile file) throws IOException { - Map payload = new HashMap<>(); - InputStream fileInputStream = file.getInputStream(); - scriptId = scriptId == null ? 0 : scriptId; - contentEncoding = contentEncoding == null ? "" : contentEncoding; - try { - Script script = new ScriptDao().findById(scriptId); - if (script == null){ - script = new Script(); - script.setName("New"); - script.setCreator("System"); - } else { - payload.put("message", "Script with script ID " + scriptId + " overwritten with new script content"); - } - - ScriptProcessor scriptProcessor = new ServletInjector().getManagedBean(servletContext, - ScriptProcessor.class); - - scriptProcessor.setScript(script); - if (StringUtils.isNotEmpty(name)) { - script.setName(name); - } - - BufferedReader bufferedReader = StringUtils.equalsIgnoreCase(contentEncoding, "gzip") ? - new BufferedReader(new InputStreamReader(new GZIPInputStream(fileInputStream))) : - new BufferedReader(new InputStreamReader(fileInputStream)); - scriptProcessor.getScriptSteps(bufferedReader, new ArrayList<>()); - script = new ScriptDao().saveOrUpdate(script); - sendMsg(script, ModificationType.UPDATE); - if (scriptId.equals(0)) { - payload.put("message", "Script with new script ID " + script.getId() + " has been uploaded"); - } else { - if (!payload.containsKey("message")) { - payload.put("message", "Existing script with script ID " + scriptId + " could not be found, created new script " + script.getId()); - } - } - payload.put("scriptId", Integer.toString(script.getId())); - } catch (Exception e) { - LOGGER.error("Error uploading script file: " + e.getMessage(), e); - throw new GenericServiceCreateOrUpdateException("scripts", "new script via script upload", e); - } finally { - try { - fileInputStream.close(); - } catch (IOException e) {} - } - return payload; - } - - private void sendMsg(BaseEntity entity, ModificationType type) { - MessageSender sender = new ServletInjector().getManagedBean(servletContext, MessageSender.class); - sender.sendEvent(new ModifiedEntityMessage(entity.getClass(), entity.getId(), type)); - } - @Override public String deleteExternalScript(Integer externalScriptId) { ExternalScriptDao dao = new ExternalScriptDao(); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java index c4ed0f9a8..992be4d8a 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java @@ -34,16 +34,11 @@ public static DataFileDescriptor dataFileToDescriptor(DataFile dataFile) { ret.setModified(dataFile.getModified()); ret.setCreator(dataFile.getCreator()); ret.setName(dataFile.getPath()); - ret.setDataUrl(getRelativeDataUrl(dataFile.getId())); +// ret.setDataUrl(getRelativeDataUrl(dataFile.getId())); TODO ret.setComments(dataFile.getComments()); return ret; } - private static String getRelativeDataUrl(int id) { - String url = config.getControllerBase() + "/api/v2/datafiles/content?id={id}"; - return url.replace("{id}", Integer.toString(id)); - } - /** * @param dao * @param to the descriptor to convert diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ResponseUtil.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ResponseUtil.java index b25a9ae69..0ccdc3a91 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ResponseUtil.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ResponseUtil.java @@ -12,15 +12,16 @@ import com.intuit.tank.harness.data.HDWorkload; import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.Workload; -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; import com.intuit.tank.transform.scriptGenerator.ConverterUtil; import com.amazonaws.xray.AWSXRay; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.CacheControl; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; @@ -33,17 +34,17 @@ private ResponseUtil() { // empty private constructor to implement util pattern } - public static StreamingResponseBody getXMLStream(Object toMarshall) { + public static StreamingOutput getXMLStream(Object toMarshall) { return (OutputStream outputStream) -> { AWSXRay.beginSubsegment("JAXB.Marshal." + toMarshall.getClass().getSimpleName()); try { - JAXBContext ctx = JAXBContext.newInstance(toMarshall.getClass()); + JAXBContext ctx = JAXBContext.newInstance(toMarshall.getClass().getPackage().getName()); Marshaller marshaller = ctx.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(toMarshall, outputStream); } catch (JAXBException e) { LOG.error("Error Marshalling XML to Stream: " + e.toString(), e); - throw new GenericServiceResourceNotFoundException("scripts", "script file", e); + throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); } finally { AWSXRay.endSubsegment(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java new file mode 100644 index 000000000..0d72083c4 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java @@ -0,0 +1,29 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.util; + +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.servlet.ServletContext; + +public class ServletInjector { + + private BeanManager getBeanManager(ServletContext servletContext) { + return (BeanManager) servletContext + .getAttribute("org.jboss.weld.environment.servlet.javax.enterprise.inject.spi.BeanManager"); + } + + @SuppressWarnings({ "unchecked" }) + public T getManagedBean(ServletContext servletContext, Class beanClass) { + BeanManager beanManager = getBeanManager(servletContext); + Bean bean = beanManager.getBeans(beanClass).iterator().next(); + CreationalContext cc = beanManager.createCreationalContext(bean); + return (T) beanManager.getReference(bean, beanClass, cc); + } +} diff --git a/rest-mvc/src/main/resources/application.yml b/rest-mvc/src/main/resources/application.yml index 8d7e4c8d0..1a4b09564 100644 --- a/rest-mvc/src/main/resources/application.yml +++ b/rest-mvc/src/main/resources/application.yml @@ -31,10 +31,6 @@ server: cookie: secure: true http-only: true - multipart: - enabled: true - max-file-size: 200MB - max-request-size: 200MB tomcat: accesslog: request-attributes-enabled: true diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileControllerTest.java index 0534b772e..6e0e35dee 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/DataFileControllerTest.java @@ -10,11 +10,9 @@ import com.intuit.tank.project.DataFile; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptorContainer; -import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; import com.intuit.tank.rest.mvc.rest.services.datafiles.DataFileServiceV2; import com.intuit.tank.rest.mvc.rest.util.DataFileServiceUtil; -import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -25,7 +23,6 @@ import static org.mockito.Mockito.when; import org.springframework.http.ResponseEntity; -import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; @@ -35,7 +32,9 @@ import java.io.IOException; import java.io.ByteArrayOutputStream; import java.nio.file.Files; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; public class DataFileControllerTest { @@ -116,37 +115,6 @@ public void testGetDatafileContent() throws IOException { verify(datafileService).getDatafileContent(2, 5, 10); } - @Test - public void testDownloadDatafile() throws IOException { - Map payload = new HashMap(); - File testCSV = new File("src/test/resources/test.csv"); - StreamingResponseBody responseBody = outputStream -> { - Files.copy(testCSV.toPath(), outputStream); - }; - String filename = "test.csv"; - payload.put(filename, responseBody); - when(datafileService.downloadDatafile(4)).thenReturn(payload); - ResponseEntity result = datafileController.downloadDatafile(4); - assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); - assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); - assertEquals(200, result.getStatusCodeValue()); - verify(datafileService).downloadDatafile(4); - } - - @Test - public void testUploadDatafile() throws IOException { - Map payload = new HashMap<>(); - payload.put("datafileId", "6"); - payload.put("message", "Datafile with new datafile ID 6 has been uploaded"); - when(datafileService.uploadDatafile(0, "gzip", null)).thenReturn(payload); - ResponseEntity> result = datafileController.uploadDatafile("gzip", 0, null); - Map response = result.getBody(); - assertEquals("6", response.get("datafileId")); - assertTrue(response.get("message").contains("uploaded")); - assertEquals(201, result.getStatusCodeValue()); - verify(datafileService).uploadDatafile(0, "gzip", null); - } - @Test public void testDeleteDatafile() { when(datafileService.deleteDatafile(1)).thenReturn(""); diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptControllerTest.java index d77dd84fa..d2ae13e2c 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ScriptControllerTest.java @@ -15,7 +15,6 @@ import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescription; import com.intuit.tank.rest.mvc.rest.services.scripts.ScriptServiceV2; -import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptServiceUtil; import org.junit.jupiter.api.BeforeEach; @@ -28,15 +27,13 @@ import static org.mockito.Mockito.when; import org.springframework.http.ResponseEntity; -import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.servlet.http.HttpServletRequest; -import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; import java.util.stream.Collectors; public class ScriptControllerTest { @@ -89,15 +86,15 @@ public void testGetScript() { Script script = new Script(); script.setName("testName"); script.setProductName("testProductName"); - when(scriptService.getScript(2)).thenReturn(ScriptServiceUtil.scriptToScriptDescription(script)); - ResponseEntity result = scriptController.getScript(2); + when(scriptService.getScript(2)).thenReturn(ScriptServiceUtil.scriptToTransferObject(script)); + ResponseEntity result = scriptController.getScript(2); assertEquals("testName", result.getBody().getName()); assertEquals("testProductName", result.getBody().getProductName()); assertEquals(200, result.getStatusCodeValue()); verify(scriptService).getScript(2); when(scriptService.getScript(2)).thenReturn(null); - ResponseEntity notFound = scriptController.getScript(2); + ResponseEntity notFound = scriptController.getScript(2); assertEquals(404, notFound.getStatusCodeValue()); } @@ -118,58 +115,6 @@ public void testCreateScript() { verify(scriptService).createScript(payload); } - @Test - public void testDownloadScript() throws IOException { - Map payload = new HashMap(); - ScriptTO scriptTO = new ScriptTO(); - scriptTO.setId(4); - scriptTO.setCreator("Test"); - scriptTO.setName("testName"); - scriptTO.setRuntime(3); - StreamingResponseBody streamingResponse = ResponseUtil.getXMLStream(scriptTO); - String filename = "test_TS.xml"; - payload.put(filename, streamingResponse); - when(scriptService.downloadScript(4)).thenReturn(payload); - ResponseEntity result = scriptController.downloadScript(4); - assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); - assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); - assertEquals(200, result.getStatusCodeValue()); - verify(scriptService).downloadScript(4); - } - - @Test - public void testDownloadHarnessScript() throws IOException { - Map payload = new HashMap(); - ScriptTO scriptTO = new ScriptTO(); - scriptTO.setId(4); - scriptTO.setCreator("Test"); - scriptTO.setName("testName"); - scriptTO.setRuntime(3); - StreamingResponseBody streamingResponse = ResponseUtil.getXMLStream(scriptTO); - String filename = "test_H.xml"; - payload.put(filename, streamingResponse); - when(scriptService.downloadHarnessScript(4)).thenReturn(payload); - ResponseEntity result = scriptController.downloadHarnessScript(4); - assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); - assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); - assertEquals(200, result.getStatusCodeValue()); - verify(scriptService).downloadHarnessScript(4); - } - - @Test - public void testUploadScript() throws IOException { - Map payload = new HashMap<>(); - payload.put("scriptId", "7"); - payload.put("message", "Script with new script ID 7 has been uploaded"); - when(scriptService.uploadProxyScript("testName", 0, "gzip", null)).thenReturn(payload); - ResponseEntity> result = scriptController.uploadScript("gzip", "testName", 0, null); - Map response = result.getBody(); - assertEquals("7", response.get("scriptId")); - assertTrue(response.get("message").contains("uploaded")); - assertEquals(201, result.getStatusCodeValue()); - verify(scriptService).uploadProxyScript("testName", 0, "gzip", null); - } - @Test public void testDeleteScript() { when(scriptService.deleteScript(1)).thenReturn(""); @@ -241,24 +186,6 @@ public void testCreateExternalScript() { verify(scriptService).createExternalScript(payload); } - @Test - public void testDownloadExternalScript() throws IOException { - Map payload = new HashMap(); - ExternalScriptTO externalScriptTO = new ExternalScriptTO(); - externalScriptTO.setId(5); - externalScriptTO.setCreator("Test"); - externalScriptTO.setName("testExternalName"); - StreamingResponseBody streamingResponse = ResponseUtil.getXMLStream(externalScriptTO); - String filename = "test_ETS.xml"; - payload.put(filename, streamingResponse); - when(scriptService.downloadExternalScript(5)).thenReturn(payload); - ResponseEntity result = scriptController.downloadExternalScript(5); - assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); - assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); - assertEquals(200, result.getStatusCodeValue()); - verify(scriptService).downloadExternalScript(5); - } - @Test public void testDeleteExternalScript() { when(scriptService.deleteExternalScript(2)).thenReturn(""); diff --git a/web/web_ui/src/main/webapp/WEB-INF/web.xml b/web/web_ui/src/main/webapp/WEB-INF/web.xml index d34f08a97..8f605818d 100644 --- a/web/web_ui/src/main/webapp/WEB-INF/web.xml +++ b/web/web_ui/src/main/webapp/WEB-INF/web.xml @@ -71,12 +71,6 @@ 0 true - - /tmp - 200000000 - 200000000 - 1048576 - rest-mvc From 96c58f85cd071ddd8dd31237f01cb3275080d19e Mon Sep 17 00:00:00 2001 From: zkofiro Date: Mon, 27 Mar 2023 17:19:36 -0700 Subject: [PATCH 06/73] feat: Updated clients, new routes, status response from agent/job ops, and testing agent client with APIHarness --- agent/agent_standalone/pom.xml | 2 +- .../agent/StandaloneAgentStartup.java | 8 +-- agent/apiharness/pom.xml | 2 +- .../com/intuit/tank/harness/APIMonitor.java | 12 ++-- .../intuit/tank/harness/APITestHarness.java | 4 +- rest-mvc/pom.xml | 41 ++++++++++++- .../rest/mvc/rest/clients/AgentClient.java | 36 ++++++++--- .../rest/mvc/rest/clients/DataFileClient.java | 39 +++++++++++- .../rest/mvc/rest/clients/FilterClient.java | 21 +++++-- .../tank/rest/mvc/rest/clients/JobClient.java | 45 +++++--------- .../rest/mvc/rest/clients/ProjectClient.java | 14 +++++ .../rest/mvc/rest/clients/ScriptClient.java | 60 ++++++++++++++++++- .../mvc/rest/controllers/AgentController.java | 46 ++++++++------ .../mvc/rest/controllers/JobController.java | 40 ++++++------- .../rest/controllers/ProjectController.java | 35 +++++++++++ .../rest/services/agent/AgentServiceV2.java | 26 ++++++-- .../services/agent/AgentServiceV2Impl.java | 26 ++++++-- .../services/filters/FilterServiceV2Impl.java | 2 +- .../mvc/rest/services/jobs/JobServiceV2.java | 20 +++++-- .../rest/services/jobs/JobServiceV2Impl.java | 16 +++-- .../services/projects/ProjectServiceV2.java | 23 +++++++ .../projects/ProjectServiceV2Impl.java | 39 +++++++++++- .../services/scripts/ScriptServiceV2Impl.java | 2 +- .../rest/controllers/AgentControllerTest.java | 35 ++++++++--- .../rest/controllers/JobControllerTest.java | 30 ++++++---- .../controllers/ProjectControllerTest.java | 36 +++++++++++ .../v1/automation/AutomationServiceV1.java | 4 +- .../tank/service/util/MessageSender.java | 44 ++++++++++++++ 28 files changed, 570 insertions(+), 138 deletions(-) create mode 100644 rest/service/common/src/main/java/com/intuit/tank/service/util/MessageSender.java diff --git a/agent/agent_standalone/pom.xml b/agent/agent_standalone/pom.xml index 96da7eaff..42e58a0e4 100755 --- a/agent/agent_standalone/pom.xml +++ b/agent/agent_standalone/pom.xml @@ -16,7 +16,7 @@ ${project.groupId} - agent-client + tank-api ${project.version} diff --git a/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java b/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java index 95b4a6e01..c7d4bb0c4 100644 --- a/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java +++ b/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java @@ -28,7 +28,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.AgentServiceClient; +import com.intuit.tank.rest.mvc.rest.clients.AgentClient; import com.intuit.tank.harness.HostInfo; import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentAvailabilityStatus; @@ -45,7 +45,7 @@ public class StandaloneAgentStartup implements Runnable { private String controllerBase; private AgentAvailability currentAvailability; - private AgentServiceClient agentClient; + private AgentClient agentClient; private String instanceId; private String hostname; private int capacity = 4000; @@ -53,7 +53,7 @@ public class StandaloneAgentStartup implements Runnable { @Override public void run() { CommandListener.startHttpServer(CommandListener.PORT, this); - agentClient = new AgentServiceClient(controllerBase); + agentClient = new AgentClient(controllerBase); if (hostname != null) { instanceId = hostname; @@ -152,7 +152,7 @@ private void sendAvailability() { currentAvailability.getInstanceUrl(), currentAvailability.getCapacity(), currentAvailability.getAvailabilityStatus()); LOG.info("Sending availaability: " + ToStringBuilder.reflectionToString(availability)); - agentClient.standaloneAgentAvailable(availability); + agentClient.setStandaloneAgentAvailability(availability); } public static void main(String[] args) { diff --git a/agent/apiharness/pom.xml b/agent/apiharness/pom.xml index 8238f2d8d..ea3b6af67 100644 --- a/agent/apiharness/pom.xml +++ b/agent/apiharness/pom.xml @@ -29,7 +29,7 @@ ${project.groupId} - agent-client + tank-api ${project.version} diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java index 43ebf6185..ac5adeaa2 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java @@ -18,7 +18,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.CloudServiceClient; +import com.intuit.tank.rest.mvc.rest.clients.AgentClient; import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.api.model.v1.cloud.VMStatus; import com.intuit.tank.api.model.v1.cloud.ValidationStatus; @@ -36,7 +36,7 @@ public class APIMonitor implements Runnable { private static final int MIN_REPORT_TIME = 15000; private static Logger LOG = LogManager.getLogger(APIMonitor.class); private static boolean doMonitor = true; - private static CloudServiceClient client; + private static AgentClient client; private static CloudVmStatus status; private long reportInterval = APIMonitor.MIN_REPORT_TIME; private boolean isLocal; @@ -45,7 +45,7 @@ public APIMonitor(Boolean isLocal, CloudVmStatus vmStatus) { this.isLocal = isLocal; status = vmStatus; try { - client = new CloudServiceClient(APITestHarness.getInstance().getTankConfig().getControllerBase()); + client = new AgentClient(APITestHarness.getInstance().getTankConfig().getControllerBase()); reportInterval = Math.max(APITestHarness.getInstance().getTankConfig().getAgentConfig() .getStatusReportIntervalMilis(reportInterval), MIN_REPORT_TIME); } catch (Exception e) { @@ -65,7 +65,7 @@ public void run() { newStatus.setTotalTps(tpsInfo.getTotalTps()); sendTps(tpsInfo); } - if (!isLocal) client.setVmStatus(newStatus.getInstanceId(), newStatus); + if (!isLocal) client.setInstanceStatus(newStatus.getInstanceId(), newStatus); APITestHarness.getInstance().checkAgentThreads(); Thread.sleep(reportInterval); } catch (Exception t) { @@ -73,7 +73,7 @@ public void run() { } } CloudVmStatus newStatus = createStatus(APITestHarness.getInstance().getStatus()); - client.setVmStatus(newStatus.getInstanceId(), newStatus); + client.setInstanceStatus(newStatus.getInstanceId(), newStatus); } private void sendTps(final TPSInfoContainer tpsInfo) { @@ -136,7 +136,7 @@ public synchronized static void setJobStatus(JobStatus jobStatus) { stats.getMaxVirtualUsers(), stats.getCurrentNumberUsers(), status.getStartTime(), endTime); status.setUserDetails(APITestHarness.getInstance().getUserTracker().getSnapshot()); - client.setVmStatus(status.getInstanceId(), status); + client.setInstanceStatus(status.getInstanceId(), status); } catch (Exception e) { LOG.error("Error sending status to controller: " + e.toString(), e); } diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java index 0501e1e69..e51e9195e 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java @@ -41,7 +41,7 @@ import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.message.ObjectMessage; -import com.intuit.tank.AgentServiceClient; +import com.intuit.tank.rest.mvc.rest.clients.AgentClient; import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.api.model.v1.cloud.VMStatus; import com.intuit.tank.api.model.v1.cloud.ValidationStatus; @@ -252,7 +252,7 @@ private void startHttp(String baseUrl) { if (baseUrl == null) { baseUrl = AmazonUtil.getControllerBaseUrl(); } - AgentServiceClient client = new AgentServiceClient(baseUrl); + AgentClient client = new AgentClient(baseUrl); String instanceUrl = null; int retryCount = 0; while (instanceUrl == null) { diff --git a/rest-mvc/pom.xml b/rest-mvc/pom.xml index ea39068a1..f594027ab 100644 --- a/rest-mvc/pom.xml +++ b/rest-mvc/pom.xml @@ -29,11 +29,50 @@ org.springframework.boot spring-boot-starter-webflux + + + org.apache.logging.log4j + log4j-to-slf4j + + + + + org.projectlombok + lombok + RELEASE + compile + + ${project.groupId} - automation-service + script-engine ${project.version} + + + ${project.groupId} + tank-vm-manager + ${project.version} + + + + ${project.groupId} + tank-script-processor + ${project.version} + + + + ${project.groupId} + automation-api + ${project.version} + + + + ${project.groupId} + cloud-service + ${project.version} + + diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java index 807dcc401..37b3d886d 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -10,6 +10,7 @@ import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +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.agent.messages.Headers; @@ -54,6 +55,7 @@ public String getSettings() { public Mono getSupportFiles() { return client.get() .uri(urlBuilder.buildUrl("/support-files")) + .accept(MediaType.APPLICATION_OCTET_STREAM) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) @@ -103,6 +105,20 @@ public TankHttpClientDefinitionContainer getClients() { .block(); } + public Void setStandaloneAgentAvailability(AgentAvailability availability) { + return client.post() + .uri(urlBuilder.buildUrl("/availability")) + .contentType(MediaType.APPLICATION_JSON) + .body(Mono.just(availability), AgentAvailability.class) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(Void.class) + .block(); + } + public CloudVmStatus getInstanceStatus(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/status/", instanceId)) @@ -130,51 +146,55 @@ public Void setInstanceStatus(String instanceId, CloudVmStatus VmStatus) { .block(); } - public Void stopInstance(String instanceId) { + public String stopInstance(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/stop/", instanceId)) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } - public Void pauseInstance(String instanceId) { + public String pauseInstance(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/pause/", instanceId)) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } - public Void resumeInstance(String instanceId) { + public String resumeInstance(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/resume/", instanceId)) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } - public Void killInstance(String instanceId) { + public String killInstance(String instanceId) { return client.get() .uri(urlBuilder.buildUrl("/instance/kill/", instanceId)) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java index 1b1979957..547c6abfc 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java @@ -10,9 +10,14 @@ import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptorContainer; +import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; +import java.util.Map; + public class DataFileClient extends BaseClient{ private static final String SERVICE_BASE_URL = "/api/v2/datafiles"; @@ -56,13 +61,11 @@ public DataFileDescriptor getDatafile(Integer datafileId) { .block(); } - public String getDatafileContent(Integer id, Integer offset, Integer lines) { + public String getDatafileContent(Integer id) { return client.get() .uri(uriBuilder -> uriBuilder .path(urlBuilder.buildUrl("/content")) .queryParam("id", id) - .queryParam("offset", offset) - .queryParam("lines", lines) .build()) .accept(MediaType.TEXT_PLAIN) .retrieve() @@ -74,6 +77,36 @@ public String getDatafileContent(Integer id, Integer offset, Integer lines) { .block(); } + public Mono downloadDatafile(Integer datafileId) { + return client.get() + .uri(urlBuilder.buildUrl("/download", datafileId)) + .accept(MediaType.APPLICATION_OCTET_STREAM) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(DataBuffer.class); + } + + public Map uploadDatafile(Integer id, MultipartFile file) { + return client.post() + .uri(uriBuilder -> uriBuilder + .path(urlBuilder.buildUrl("/upload")) + .queryParam("id", id) + .build()) + .contentType(MediaType.MULTIPART_FORM_DATA) + .accept(MediaType.APPLICATION_JSON) + .body(Mono.just(file), MultipartFile.class) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(Map.class) + .block(); + } + public String deleteDatafile(Integer datafileID) { return client.delete() .uri(urlBuilder.buildUrl("", datafileID)) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java index 324546a21..6c5371dbe 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java @@ -8,10 +8,8 @@ package com.intuit.tank.rest.mvc.rest.clients; import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; -import com.intuit.tank.rest.mvc.rest.models.filters.FilterContainer; -import com.intuit.tank.rest.mvc.rest.models.filters.FilterGroupContainer; -import com.intuit.tank.rest.mvc.rest.models.filters.FilterGroupTO; -import com.intuit.tank.rest.mvc.rest.models.filters.FilterTO; +import com.intuit.tank.rest.mvc.rest.models.filters.*; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; @@ -86,6 +84,21 @@ public FilterGroupTO getFilterGroup(Integer filterGroupId) { .block(); } + public String applyFilters(Integer scriptId, ApplyFiltersRequest request) { + return client.post() + .uri(urlBuilder.buildUrl("/apply-filters", scriptId)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.TEXT_PLAIN) + .body(Mono.just(request), ApplyFiltersRequest.class) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(String.class) + .block(); + } + public String deleteFilter(Integer filterId) { return client.delete() .uri(urlBuilder.buildUrl("", filterId)) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java index ca955ecb4..57afc00f6 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java @@ -118,93 +118,80 @@ public String getJobStatus(Integer jobId) { public String getJobVMStatuses(String jobId) { return client.get() .uri(urlBuilder.buildUrl("/instance-status", jobId)) - .accept(MediaType.TEXT_PLAIN) - .retrieve() - .onStatus(status -> status.isError(), - response -> response.bodyToMono(String.class) - .flatMap(body -> Mono.error(new ClientException(body, - response.statusCode().value())))) - .bodyToMono(String.class) - .block(); - } - - public CloudVmStatusContainer deleteProject(Integer projectId) { - return client.delete() - .uri(urlBuilder.buildUrl("", projectId)) .accept(MediaType.APPLICATION_JSON) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(CloudVmStatusContainer.class) + .bodyToMono(String.class) .block(); } // Job Status Setters - public Void startJob(Integer jobId) { + public String startJob(Integer jobId) { return client.get() .uri(urlBuilder.buildUrl("/start", jobId)) - .accept(MediaType.APPLICATION_JSON) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } - public Void stopJob(Integer jobId) { + public String stopJob(Integer jobId) { return client.get() .uri(urlBuilder.buildUrl("/stop", jobId)) - .accept(MediaType.APPLICATION_JSON) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } - public Void pauseJob(Integer jobId) { + public String pauseJob(Integer jobId) { return client.get() .uri(urlBuilder.buildUrl("/pause", jobId)) - .accept(MediaType.APPLICATION_JSON) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } - public Void resumeJob(Integer jobId) { + public String resumeJob(Integer jobId) { return client.get() .uri(urlBuilder.buildUrl("/resume", jobId)) - .accept(MediaType.APPLICATION_JSON) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } - public Void killJob(Integer jobId) { + public String killJob(Integer jobId) { return client.get() .uri(urlBuilder.buildUrl("/kill", jobId)) - .accept(MediaType.APPLICATION_JSON) + .accept(MediaType.TEXT_PLAIN) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(Void.class) + .bodyToMono(String.class) .block(); } } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java index 99774bfde..0fc4333c7 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java @@ -11,6 +11,8 @@ import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; @@ -103,6 +105,18 @@ public Map updateProject(AutomationRequest request) { .block(); } + public Mono downloadTestScriptForProject(Integer projectId) { + return client.get() + .uri(urlBuilder.buildUrl("/download", projectId)) + .accept(MediaType.APPLICATION_OCTET_STREAM) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(DataBuffer.class); //TODO: return string + } + public String deleteProject(Integer projectId) { return client.delete() .uri(urlBuilder.buildUrl("", projectId)) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java index 1b6947df0..b139ce598 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java @@ -12,6 +12,9 @@ import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; @@ -19,7 +22,7 @@ public class ScriptClient extends BaseClient{ - private static final String SERVICE_BASE_URL = "/api/v2/projects"; + private static final String SERVICE_BASE_URL = "/api/v2/scripts"; public ScriptClient(String serviceUrl) { super(serviceUrl, null, null); @@ -75,6 +78,49 @@ public ScriptTO createScript(ScriptTO scriptTo) { .block(); } + public Mono downloadScript(Integer scriptId) { + return client.get() + .uri(urlBuilder.buildUrl("/download", scriptId)) + .accept(MediaType.APPLICATION_OCTET_STREAM) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(DataBuffer.class); + } + + public Mono downloadHarnessScript(Integer scriptId) { + return client.get() + .uri(urlBuilder.buildUrl("/harness/download", scriptId)) + .accept(MediaType.APPLICATION_OCTET_STREAM) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(DataBuffer.class); //TODO: return string + } + + public Map uploadScript(String name, Integer id, MultipartFile file) { + return client.post() + .uri(uriBuilder -> uriBuilder + .path(urlBuilder.buildUrl("/upload")) + .queryParam("name", id) + .queryParam("id", id) + .build()) + .contentType(MediaType.MULTIPART_FORM_DATA) + .accept(MediaType.APPLICATION_JSON) + .body(Mono.just(file), MultipartFile.class) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(Map.class) + .block(); + } + public String deleteScript(Integer scriptId) { return client.delete() .uri(urlBuilder.buildUrl("", scriptId)) @@ -131,6 +177,18 @@ public ExternalScriptTO createExternalScript(ExternalScriptTO script) { .block(); } + public Mono downloadExternalScript(Integer externalScriptId) { + return client.get() + .uri(urlBuilder.buildUrl("/external/download", externalScriptId)) + .accept(MediaType.APPLICATION_OCTET_STREAM) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(DataBuffer.class); + } + public String deleteExternalScript(Integer externalScriptId) { return client.delete() .uri(urlBuilder.buildUrl("/external", externalScriptId)) 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..2e24b2d05 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; @@ -110,6 +111,17 @@ 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") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully set agent availability"), + @ApiResponse(responseCode = "400", description = "Bad request", content = @Content) + }) + public ResponseEntity setStandaloneAgentAvailability( + @RequestBody @Parameter(description = "Agent availability request to update standalone agent availability", required = true) AgentAvailability 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") @@ -137,47 +149,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) }) - 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) }) - 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) }) - 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) }) - 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/JobController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java index 29bf5023c..9008d9f6d 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 @@ -146,58 +146,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) }) - 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) }) - 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) }) - 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) }) - 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) }) - 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..9b91006c3 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 name/project ID key value pairs", summary = "Get all project name with project IDs") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully found all project names with IDs"), + @ApiResponse(responseCode = "404", description = "All project name 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 script harness XML file", summary = "Download the project's script harness file") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully downloaded project's script harness file", content = @Content), + @ApiResponse(responseCode = "404", description = "Project's script 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/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/filters/FilterServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java index 4a110e170..9a6d7d479 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java @@ -25,7 +25,7 @@ import com.intuit.tank.rest.mvc.rest.models.filters.ApplyFiltersRequest; import com.intuit.tank.rest.mvc.rest.util.FilterServiceUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptFilterUtil; -import com.intuit.tank.service.impl.v1.automation.MessageSender; +import com.intuit.tank.service.util.MessageSender; import com.intuit.tank.service.util.ServletInjector; import com.intuit.tank.vm.settings.ModifiedEntityMessage; import com.intuit.tank.vm.settings.ModificationType; 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..a43292c9b 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 @@ -45,6 +45,7 @@ import com.intuit.tank.util.TestParameterContainer; import com.intuit.tank.util.CreateDateComparator; import com.intuit.tank.util.CreateDateComparator.SortOrder; +import com.intuit.tank.vm.api.enumerated.JobQueueStatus; import com.intuit.tank.vm.api.enumerated.VMRegion; import com.intuit.tank.vm.api.enumerated.TerminationPolicy; import com.intuit.tank.vm.common.util.ReportUtil; @@ -198,12 +199,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 +213,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 +227,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 +241,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 +255,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); 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..071804a8e 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 projects names along with projectId + * + * @throws GenericServiceResourceNotFoundException + * if there is an error returning all projects + * + * @return list of projects < name, id > 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 script harness XML file + * + * @throws GenericServiceResourceNotFoundException + * if there are errors downloading script harness + * + * @return project's script 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..1f73824f1 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,18 +24,21 @@ 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.service.impl.v1.automation.MessageSender; +import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; +import com.intuit.tank.service.util.MessageSender; import com.intuit.tank.service.util.ServletInjector; import com.intuit.tank.vm.api.enumerated.ScriptDriver; import com.intuit.tank.vm.api.enumerated.TerminationPolicy; 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,18 @@ public ProjectContainer getAllProjects(){ } } + @Override + public Map getAllProjectNames(){ + try { + Map projects = new HashMap<>(); + List all = new ProjectDao().findAll(); + return all.stream().collect(Collectors.toMap(Project::getName, Project::getId)); + } 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 +176,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 script harness file: " + e.getMessage(), e); + throw new GenericServiceResourceNotFoundException("projects", "project script 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/ScriptServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/scripts/ScriptServiceV2Impl.java index 660807455..f324f22a1 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 @@ -20,7 +20,7 @@ import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptServiceUtil; import com.intuit.tank.script.processor.ScriptProcessor; -import com.intuit.tank.service.impl.v1.automation.MessageSender; +import com.intuit.tank.service.util.MessageSender; import com.intuit.tank.service.util.ServletInjector; import com.intuit.tank.transform.scriptGenerator.ConverterUtil; import com.intuit.tank.vm.settings.ModifiedEntityMessage; diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java index f70a3c6ac..898a0a70b 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java @@ -11,6 +11,8 @@ import com.intuit.tank.rest.mvc.rest.services.agent.AgentServiceV2; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; +import com.intuit.tank.vm.agent.messages.AgentAvailability; +import com.intuit.tank.vm.agent.messages.AgentAvailabilityStatus; import com.intuit.tank.vm.agent.messages.AgentData; import com.intuit.tank.vm.agent.messages.AgentTestStartData; import com.intuit.tank.vm.agent.messages.Header; @@ -130,6 +132,15 @@ public void testAgentReady() { verify(agentService).agentReady(testAgentData); } + @Test + public void testStandaloneAgentAvailability() { + AgentAvailability availability = new AgentAvailability("testInstanceId", + "testInstanceUrl", 5, + AgentAvailabilityStatus.AVAILABLE); + ResponseEntity result = agentController.setStandaloneAgentAvailability(availability); + assertEquals(200, result.getStatusCodeValue()); + } + // Instance status operations @Test public void testGetInstanceStatus() { @@ -163,29 +174,37 @@ public void testSetInstanceStatus() { @Test public void testStopInstance() { - ResponseEntity result = agentController.stopInstance("testInstanceIdAPIV2"); - assertEquals(204, result.getStatusCodeValue()); + when(agentService.stopInstance("testInstanceIdAPIV2")).thenReturn("stopping"); + ResponseEntity result = agentController.stopInstance("testInstanceIdAPIV2"); + assertEquals("stopping", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(agentService).stopInstance("testInstanceIdAPIV2"); } @Test public void testPauseInstance() { - ResponseEntity result = agentController.pauseInstance("testInstanceIdAPIV2"); - assertEquals(204, result.getStatusCodeValue()); + when(agentService.pauseInstance("testInstanceIdAPIV2")).thenReturn("rampPaused"); + ResponseEntity result = agentController.pauseInstance("testInstanceIdAPIV2"); + assertEquals("rampPaused", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(agentService).pauseInstance("testInstanceIdAPIV2"); } @Test public void testResumeInstance() { - ResponseEntity result = agentController.resumeInstance("testInstanceIdAPIV2"); - assertEquals(204, result.getStatusCodeValue()); + when(agentService.resumeInstance("testInstanceIdAPIV2")).thenReturn("running"); + ResponseEntity result = agentController.resumeInstance("testInstanceIdAPIV2"); + assertEquals("running", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(agentService).resumeInstance("testInstanceIdAPIV2"); } @Test public void testKillInstance() { - ResponseEntity result = agentController.killInstance("testInstanceIdAPIV2"); - assertEquals(204, result.getStatusCodeValue()); + when(agentService.killInstance("testInstanceIdAPIV2")).thenReturn("shutting_down"); + ResponseEntity result = agentController.killInstance("testInstanceIdAPIV2"); + assertEquals("shutting_down", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(agentService).killInstance("testInstanceIdAPIV2"); } } diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java index 3c54f931d..09f092425 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java @@ -195,36 +195,46 @@ public void testGetJobVMStatuses() { @Test public void testStartJob() { - ResponseEntity result = jobController.startJob(385594786); - assertEquals(204, result.getStatusCodeValue()); + when(jobService.startJob(385594786)).thenReturn("Starting"); + ResponseEntity result = jobController.startJob(385594786); + assertEquals("Starting", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(jobService).startJob(385594786); } @Test public void testStopJob() { - ResponseEntity result = jobController.stopJob(808242333); - assertEquals(204, result.getStatusCodeValue()); + when(jobService.stopJob(808242333)).thenReturn("Stopped"); + ResponseEntity result = jobController.stopJob(808242333); + assertEquals("Stopped", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(jobService).stopJob(808242333); } @Test public void testPauseJob() { - ResponseEntity result = jobController.pauseJob(375886587); - assertEquals(204, result.getStatusCodeValue()); + when(jobService.pauseJob(375886587)).thenReturn("RampPaused"); + ResponseEntity result = jobController.pauseJob(375886587); + assertEquals("RampPaused", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(jobService).pauseJob(375886587); } @Test public void testResumeJob() { - ResponseEntity result = jobController.resumeJob(100403047); - assertEquals(204, result.getStatusCodeValue()); + when(jobService.resumeJob(100403047)).thenReturn("Running"); + ResponseEntity result = jobController.resumeJob(100403047); + assertEquals("Running", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(jobService).resumeJob(100403047); } @Test public void testKillJob() { - ResponseEntity result = jobController.killJob(482937134); - assertEquals(204, result.getStatusCodeValue()); + when(jobService.killJob(482937134)).thenReturn("Completed"); + ResponseEntity result = jobController.killJob(482937134); + assertEquals("Completed", result.getBody()); + assertEquals(200, result.getStatusCodeValue()); verify(jobService).killJob(482937134); } } diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ProjectControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ProjectControllerTest.java index 55642122f..415f1083c 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ProjectControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/ProjectControllerTest.java @@ -7,12 +7,14 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; import com.intuit.tank.rest.mvc.rest.services.projects.ProjectServiceV2; import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest; import com.intuit.tank.rest.mvc.rest.models.projects.AutomationRequest.AutomationRequestBuilder; +import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -23,11 +25,14 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.springframework.http.ResponseEntity; +import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.servlet.http.HttpServletRequest; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -79,6 +84,17 @@ public void testGetAllProjects() { verify(projectService).getAllProjects(); } + @Test + public void testGetAllProjectNames() { + Map projectMap = new HashMap<>(); + projectMap.put("testProject", 3); + when(projectService.getAllProjectNames()).thenReturn(projectMap); + ResponseEntity> result = projectController.getAllProjectNames(); + assertEquals(3, result.getBody().get("testProject")); + assertEquals(200, result.getStatusCodeValue()); + verify(projectService).getAllProjectNames(); + } + @Test public void testGetProject() { ProjectTO testProject = new ProjectTO(); @@ -130,6 +146,26 @@ public void testUpdateProject() { verify(projectService).updateProject(1, request); } + @Test + public void testDownloadTestScriptForProject() throws IOException { + Map payload = new HashMap(); + ProjectTO projectTO = new ProjectTO(); + projectTO.setId(4); + projectTO.setCreator("Test"); + projectTO.setName("testName"); + projectTO.setLocation("testLocation"); + projectTO.setProductName("testProductName"); + StreamingResponseBody streamingResponse = ResponseUtil.getXMLStream(projectTO); + String filename = "project_test_H.xml"; + payload.put(filename, streamingResponse); + when(projectService.downloadTestScriptForProject(4)).thenReturn(payload); + ResponseEntity result = projectController.downloadTestScriptForProject(4); + assertEquals(MediaType.APPLICATION_OCTET_STREAM, result.getHeaders().getContentType()); + assertEquals(filename, result.getHeaders().getContentDisposition().getFilename()); + assertEquals(200, result.getStatusCodeValue()); + verify(projectService).downloadTestScriptForProject(4); + } + @Test public void testDeleteProject() { when(projectService.deleteProject(2)).thenReturn(""); diff --git a/rest/service/automation/src/main/java/com/intuit/tank/service/impl/v1/automation/AutomationServiceV1.java b/rest/service/automation/src/main/java/com/intuit/tank/service/impl/v1/automation/AutomationServiceV1.java index 6353aafdf..e3895f074 100644 --- a/rest/service/automation/src/main/java/com/intuit/tank/service/impl/v1/automation/AutomationServiceV1.java +++ b/rest/service/automation/src/main/java/com/intuit/tank/service/impl/v1/automation/AutomationServiceV1.java @@ -77,11 +77,11 @@ import com.intuit.tank.project.DataFile; import com.intuit.tank.project.EntityVersion; import com.intuit.tank.project.JobConfiguration; -import com.intuit.tank.project.JobDetailFormatter; +import com.intuit.tank.rest.mvc.rest.util.JobDetailFormatter; import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.JobQueue; import com.intuit.tank.project.JobRegion; -import com.intuit.tank.project.JobValidator; +import com.intuit.tank.rest.mvc.rest.util.JobValidator; import com.intuit.tank.project.Project; import com.intuit.tank.project.Script; import com.intuit.tank.project.ScriptFilter; diff --git a/rest/service/common/src/main/java/com/intuit/tank/service/util/MessageSender.java b/rest/service/common/src/main/java/com/intuit/tank/service/util/MessageSender.java new file mode 100644 index 000000000..dcd4c7185 --- /dev/null +++ b/rest/service/common/src/main/java/com/intuit/tank/service/util/MessageSender.java @@ -0,0 +1,44 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.service.util; + +/* + * #%L + * Automation Rest Service + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import com.intuit.tank.vm.settings.ModifiedEntityMessage; + +import javax.annotation.Nonnull; +import javax.enterprise.event.Event; +import javax.inject.Inject; + +/** + * MessageSender + * + * @author dangleton + * + */ +public class MessageSender { + + @Inject + private Event eventSender; + + /** + * Fires the specified event + * + * @param msg + */ + public void sendEvent(@Nonnull ModifiedEntityMessage msg) { + eventSender.fire(msg); + } +} From c550a9eca8fd80f82ac215fb78faa45cb4819f30 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Mon, 27 Mar 2023 17:38:53 -0700 Subject: [PATCH 07/73] fix: listing only user-facing endpoints --- .../tank/rest/mvc/rest/controllers/AgentController.java | 6 +++--- 1 file changed, 3 insertions(+), 3 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 2e24b2d05..7d99aea64 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 @@ -81,7 +81,7 @@ 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) @@ -112,7 +112,7 @@ public ResponseEntity getClients() { } @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") + @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 = "Bad request", content = @Content) @@ -138,7 +138,7 @@ public ResponseEntity getInstanceStatus(@PathVariable @Parameter( } @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) From ae9923dffd5f21ed4a91addaf87cfef73dd7b175 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Mon, 27 Mar 2023 18:05:51 -0700 Subject: [PATCH 08/73] fix: small updates to deps + docs for client changes --- rest-mvc/pom.xml | 2 +- .../rest/mvc/rest/controllers/ProjectController.java | 10 +++++----- .../rest/mvc/rest/services/jobs/JobServiceV2Impl.java | 1 - .../mvc/rest/services/projects/ProjectServiceV2.java | 6 +++--- .../rest/services/projects/ProjectServiceV2Impl.java | 4 ++-- 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/rest-mvc/pom.xml b/rest-mvc/pom.xml index f594027ab..a6cafe365 100644 --- a/rest-mvc/pom.xml +++ b/rest-mvc/pom.xml @@ -64,7 +64,7 @@ ${project.groupId} - automation-api + api ${project.version} 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 9b91006c3..dc7482796 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 @@ -60,9 +60,9 @@ public ResponseEntity getAllProjects() { } @RequestMapping(value = "/names", method = RequestMethod.GET) - @Operation(description = "Returns all project name/project ID key value pairs", summary = "Get all project name with project IDs") + @Operation(description = "Returns all project name/project ID key value pairs", summary = "Get all project names with project IDs") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully found all project names with IDs"), + @ApiResponse(responseCode = "200", description = "Successfully found all project names with IDs", content = @Content), @ApiResponse(responseCode = "404", description = "All project name with IDs could not be found", content = @Content) }) public ResponseEntity> getAllProjectNames() { @@ -126,10 +126,10 @@ public ResponseEntity> updateProject( } @RequestMapping(value = "/download/{projectId}", method = RequestMethod.GET) - @Operation(description = "Downloads a project's script harness XML file", summary = "Download the project's script harness file") + @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 script harness file", content = @Content), - @ApiResponse(responseCode = "404", description = "Project's script harness file could not be found", content = @Content) + @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); 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 a43292c9b..0a9213103 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; 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 071804a8e..db2db21e8 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 @@ -72,12 +72,12 @@ public interface ProjectServiceV2 { public Map createProject(AutomationRequest request); /** - * Downloads a project's script harness XML file + * Downloads a project's harness XML file * * @throws GenericServiceResourceNotFoundException - * if there are errors downloading script harness + * if there are errors downloading harness file * - * @return project's script harness XML file + * @return project's harness XML file */ public Map downloadTestScriptForProject(Integer projectId); 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 1f73824f1..32fe4baf9 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 @@ -192,8 +192,8 @@ public Map downloadTestScriptForProject(Integer p return payload; } } catch (Exception e){ - LOGGER.error("Error downloading project script harness file: " + e.getMessage(), e); - throw new GenericServiceResourceNotFoundException("projects", "project script harness file", e); + LOGGER.error("Error downloading project harness file: " + e.getMessage(), e); + throw new GenericServiceResourceNotFoundException("projects", "project harness file", e); } } From 2e70ebbb676cfb995e83eed7a121e77d3b159af7 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Mon, 27 Mar 2023 18:58:45 -0700 Subject: [PATCH 09/73] fix: temp fix for tools while testing agent --- agent/apiharness/pom.xml | 6 ++++++ proxy-parent/owasp-proxy/pom.xml | 6 +++++- web/web_ui/src/main/webapp/META-INF/context.xml | 13 +++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/agent/apiharness/pom.xml b/agent/apiharness/pom.xml index ea3b6af67..5c6dab77f 100644 --- a/agent/apiharness/pom.xml +++ b/agent/apiharness/pom.xml @@ -33,6 +33,12 @@ ${project.version} + + ${project.groupId} + agent-client + ${project.version} + + ${project.groupId} harness-data diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml index 3299f5e5f..c465f8fc8 100755 --- a/proxy-parent/owasp-proxy/pom.xml +++ b/proxy-parent/owasp-proxy/pom.xml @@ -95,7 +95,11 @@ dec 0.1.2 - + + org.springframework + spring-dao + 2.0.8 + diff --git a/web/web_ui/src/main/webapp/META-INF/context.xml b/web/web_ui/src/main/webapp/META-INF/context.xml index 6517d08d0..2fb659b00 100644 --- a/web/web_ui/src/main/webapp/META-INF/context.xml +++ b/web/web_ui/src/main/webapp/META-INF/context.xml @@ -5,5 +5,18 @@ auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> + From 5c962507bc96bc075974d321bb6e17dd30710a88 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Tue, 28 Mar 2023 10:40:52 -0700 Subject: [PATCH 10/73] fix: removing unneeded files --- proxy-parent/owasp-proxy/pom.xml | 6 +----- web/web_ui/src/main/webapp/META-INF/context.xml | 13 ------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml index c465f8fc8..3299f5e5f 100755 --- a/proxy-parent/owasp-proxy/pom.xml +++ b/proxy-parent/owasp-proxy/pom.xml @@ -95,11 +95,7 @@ dec 0.1.2 - - org.springframework - spring-dao - 2.0.8 - + diff --git a/web/web_ui/src/main/webapp/META-INF/context.xml b/web/web_ui/src/main/webapp/META-INF/context.xml index 2fb659b00..6517d08d0 100644 --- a/web/web_ui/src/main/webapp/META-INF/context.xml +++ b/web/web_ui/src/main/webapp/META-INF/context.xml @@ -5,18 +5,5 @@ auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> - From bb9e9ebdc9f846d15414d0d86750e1fe93aed609 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 7 Apr 2023 09:28:59 -0700 Subject: [PATCH 11/73] fix: temp fix for client tools --- .../agent/StandaloneAgentStartup.java | 4 +- .../com/intuit/tank/agent/AgentStartup.java | 4 +- .../java/com/intuit/tank/dao/ProjectDao.java | 29 +++++++++ .../rest/mvc/rest/clients/AgentClient.java | 2 +- .../rest/mvc/rest/clients/BaseClient.java | 15 ++++- .../rest/mvc/rest/clients/DataFileClient.java | 28 ++++---- .../rest/mvc/rest/clients/ProjectClient.java | 34 ++++++---- .../rest/mvc/rest/clients/ScriptClient.java | 44 +++++++------ .../mvc/rest/controllers/AgentController.java | 2 +- .../rest/controllers/DefaultController.java | 53 +++++++++++++++ .../rest/controllers/ReportController.java | 41 ++++++++++++ .../GenericServiceBadRequestException.java | 42 ++++++++++++ ...enericServiceForbiddenAccessException.java | 45 +++++++++++++ .../projects/ProjectServiceV2Impl.java | 6 +- .../rest/services/report/ReportServiceV2.java | 39 +++++++++++ .../services/report/ReportServiceV2Impl.java | 65 +++++++++++++++++++ .../services/scripts/ScriptServiceV2Impl.java | 2 +- rest-mvc/src/main/resources/application.yml | 2 + rest/service/common/pom.xml | 7 ++ .../tank/service/util/ResponseUtil.java | 4 +- .../impl/v1/project/ProjectServiceV1.java | 5 +- .../impl/v1/script/ScriptServiceV1.java | 4 +- 22 files changed, 413 insertions(+), 64 deletions(-) create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ReportController.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericServiceBadRequestException.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericServiceForbiddenAccessException.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2Impl.java diff --git a/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java b/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java index c7d4bb0c4..73d31942c 100644 --- a/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java +++ b/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java @@ -37,10 +37,10 @@ public class StandaloneAgentStartup implements Runnable { private static Logger LOG = LogManager.getLogger(StandaloneAgentStartup.class); - public static final String SERVICE_RELATIVE_PATH = "/rest/v1/agent-service"; + public static final String SERVICE_RELATIVE_PATH = "/api/v2/agent"; private static String API_HARNESS_COMMAND = "./startAgent.sh"; public static final String METHOD_SETTINGS = "/settings"; - public static final String METHOD_SUPPORT = "/supportFiles"; + public static final String METHOD_SUPPORT = "/support-files"; private static final long PING_TIME = 1000 * 60 * 5;// five minutes private String controllerBase; diff --git a/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java b/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java index 51c9f5a90..ad76a7e08 100644 --- a/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java +++ b/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java @@ -34,10 +34,10 @@ public class AgentStartup implements Runnable { private static final Logger logger = LogManager.getLogger(AgentStartup.class); - private static final String SERVICE_RELATIVE_PATH = "/rest/v1/agent-service"; + private static final String SERVICE_RELATIVE_PATH = "/api/v2/agent"; private static final String METHOD_SETTINGS = "/settings"; private static final String API_HARNESS_COMMAND = "./startAgent.sh"; - private static final String METHOD_SUPPORT = "/supportFiles"; + private static final String METHOD_SUPPORT = "/support-files"; private static final int[] FIBONACCI = new int[] { 1, 1, 2, 3, 5, 8, 13 }; private final String controllerBaseUrl; diff --git a/data_access/src/main/java/com/intuit/tank/dao/ProjectDao.java b/data_access/src/main/java/com/intuit/tank/dao/ProjectDao.java index 576a4507b..7d7c7c7a2 100644 --- a/data_access/src/main/java/com/intuit/tank/dao/ProjectDao.java +++ b/data_access/src/main/java/com/intuit/tank/dao/ProjectDao.java @@ -176,6 +176,35 @@ public List findAll() throws HibernateException { } return results; } + + /** + * Finds all Objects of type T_ENTITY + * + * @return the nonnull list of entities + * @throws HibernateException + * if there is an error in persistence + */ + @Nonnull + public List findAllFast() throws HibernateException { + List results = Collections.emptyList(); + EntityManager em = getEntityManager(); + try { + begin(); + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery query = cb.createQuery(Project.class); + Root root = query.from(Project.class); + query.select(root); + results = em.createQuery(query).getResultList(); + commit(); + } catch (Exception e) { + rollback(); + e.printStackTrace(); + LOG.info("No entities found at all for Project"); + } finally { + cleanup(); + } + return results; + } @Nullable public Project loadScripts(Integer ProjectId) { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java index 37b3d886d..d757f6986 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -82,7 +82,7 @@ public AgentTestStartData agentReady(AgentData agentData) { public Headers getHeaders() { return client.get() .uri(urlBuilder.buildUrl("/headers")) - .accept(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_XML) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java index f32d75084..15e3b8195 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/BaseClient.java @@ -14,6 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; import com.google.common.collect.ImmutableMap; @@ -34,10 +35,20 @@ public BaseClient(String serviceUrl, final String proxyServer, final Integer pro setBaseUrl(serviceUrl); if (StringUtils.isNotEmpty(proxyServer)) { int port = proxyPort != null ? proxyPort : 80; - client = WebClient.builder().clientConnector(new ReactorClientHttpConnector(build(proxyServer, proxyPort))).build(); + client = WebClient.builder().exchangeStrategies(ExchangeStrategies.builder() + .codecs(configurer -> + configurer.defaultCodecs() + .maxInMemorySize(200 * 1024) + ) + .build()).clientConnector(new ReactorClientHttpConnector(build(proxyServer, proxyPort))).build(); } else { HttpClient httpClient = HttpClient.create().compress(true); - client = WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build(); + client = WebClient.builder().exchangeStrategies(ExchangeStrategies.builder() + .codecs(configurer -> + configurer.defaultCodecs() + .maxInMemorySize(200 * 1024 * 1024) + ) + .build()).clientConnector(new ReactorClientHttpConnector(httpClient)).build(); } LOGGER.info(new ObjectMessage(ImmutableMap.of("Message", "client for url " + baseUrl + ": proxy=" diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java index 547c6abfc..34eced2a2 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java @@ -11,6 +11,7 @@ import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptorContainer; import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; +import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.multipart.MultipartFile; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.MediaType; @@ -61,20 +62,19 @@ public DataFileDescriptor getDatafile(Integer datafileId) { .block(); } - public String getDatafileContent(Integer id) { - return client.get() - .uri(uriBuilder -> uriBuilder - .path(urlBuilder.buildUrl("/content")) - .queryParam("id", id) - .build()) - .accept(MediaType.TEXT_PLAIN) - .retrieve() - .onStatus(status -> status.isError(), - response -> response.bodyToMono(String.class) - .flatMap(body -> Mono.error(new ClientException(body, - response.statusCode().value())))) - .bodyToMono(String.class) - .block(); + public String getDatafileContent(Integer datafileId) { + return WebClient.create(urlBuilder.buildUrl("")) // need webclient.create for query params + .get() + .uri(uriBuilder -> uriBuilder.path("/content") + .queryParam("id", datafileId.toString()) + .build()) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(String.class) + .block(); } public Mono downloadDatafile(Integer datafileId) { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java index 0fc4333c7..ff7c9ed8c 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java @@ -13,10 +13,13 @@ import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.web.reactive.function.client.WebClient; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; import java.util.Map; public class ProjectClient extends BaseClient{ @@ -49,9 +52,9 @@ public ProjectContainer getProjects() { .block(); } - public Map getProjectNames() { - return client.get() - .uri(urlBuilder.buildUrl("/names")) + public Map getProjectNames() { + return WebClient.create(urlBuilder.buildUrl("/names")) + .get() .accept(MediaType.APPLICATION_JSON) .retrieve() .onStatus(status -> status.isError(), @@ -105,16 +108,21 @@ public Map updateProject(AutomationRequest request) { .block(); } - public Mono downloadTestScriptForProject(Integer projectId) { - return client.get() - .uri(urlBuilder.buildUrl("/download", projectId)) - .accept(MediaType.APPLICATION_OCTET_STREAM) - .retrieve() - .onStatus(status -> status.isError(), - response -> response.bodyToMono(String.class) - .flatMap(body -> Mono.error(new ClientException(body, - response.statusCode().value())))) - .bodyToMono(DataBuffer.class); //TODO: return string + public String downloadTestScriptForProject(Integer projectId) { + Mono dataBuffer = client.get() + .uri(urlBuilder.buildUrl("/download", projectId)) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(DataBuffer.class); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataBufferUtils.write(dataBuffer, baos) + .share().blockLast(); + + return baos.toString(); } public String deleteProject(Integer projectId) { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java index b139ce598..5797e11ad 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java @@ -15,9 +15,11 @@ import org.springframework.web.multipart.MultipartFile; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.web.reactive.function.client.WebClient; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; +import java.io.ByteArrayOutputStream; import java.util.Map; public class ScriptClient extends BaseClient{ @@ -90,28 +92,32 @@ public Mono downloadScript(Integer scriptId) { .bodyToMono(DataBuffer.class); } - public Mono downloadHarnessScript(Integer scriptId) { - return client.get() - .uri(urlBuilder.buildUrl("/harness/download", scriptId)) - .accept(MediaType.APPLICATION_OCTET_STREAM) - .retrieve() - .onStatus(status -> status.isError(), - response -> response.bodyToMono(String.class) - .flatMap(body -> Mono.error(new ClientException(body, - response.statusCode().value())))) - .bodyToMono(DataBuffer.class); //TODO: return string + public String downloadHarnessScript(Integer scriptId) { + Mono dataBuffer = client.get() + .uri(urlBuilder.buildUrl("/harness/download", scriptId)) + .retrieve() + .onStatus(status -> status.isError(), + response -> response.bodyToMono(String.class) + .flatMap(body -> Mono.error(new ClientException(body, + response.statusCode().value())))) + .bodyToMono(DataBuffer.class); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DataBufferUtils.write(dataBuffer, baos) + .share().blockLast(); + + return baos.toString(); } - public Map uploadScript(String name, Integer id, MultipartFile file) { - return client.post() - .uri(uriBuilder -> uriBuilder - .path(urlBuilder.buildUrl("/upload")) - .queryParam("name", id) - .queryParam("id", id) + public Map uploadScript(String name, Integer existingScriptId, MultipartFile file) { + String finalName = name == null ? "" : name; + Integer finalId = existingScriptId == null ? 0 :existingScriptId; + return WebClient.create(urlBuilder.buildUrl("")) // need webclient.create for query params + .get() + .uri(uriBuilder -> uriBuilder.path("/upload") + .queryParam("name", finalName) + .queryParam("id", finalId) .build()) - .contentType(MediaType.MULTIPART_FORM_DATA) - .accept(MediaType.APPLICATION_JSON) - .body(Mono.just(file), MultipartFile.class) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) 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 e89b125b8..0cc2d51e7 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 @@ -91,7 +91,7 @@ public ResponseEntity agentReady( return new ResponseEntity(agentService.agentReady(agentData), HttpStatus.OK); } - @RequestMapping(value = "/headers", method = RequestMethod.GET) + @RequestMapping(value = "/headers", method = RequestMethod.GET, produces = { MediaType.APPLICATION_XML_VALUE }) @Operation(description = "Returns agent headers", summary = "Get the agent headers") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Successfully found agent headers"), diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DefaultController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DefaultController.java index aa6afd6af..791cc9522 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DefaultController.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DefaultController.java @@ -7,6 +7,30 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; +import com.intuit.tank.rest.mvc.rest.clients.AgentClient; +import com.intuit.tank.api.model.v1.cloud.VMStatus; +import com.intuit.tank.vm.agent.messages.AgentData; +import com.intuit.tank.vm.agent.messages.AgentTestStartData; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.vm.api.enumerated.JobStatus; +import com.intuit.tank.vm.api.enumerated.VMRegion; +import com.intuit.tank.vm.api.enumerated.VMImageType; +import org.springframework.web.reactive.function.client.WebClient; +import com.intuit.tank.rest.mvc.rest.clients.DataFileClient; +import com.intuit.tank.rest.mvc.rest.clients.ProjectClient; +import com.intuit.tank.rest.mvc.rest.clients.ScriptClient; +import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.agent.messages.AgentAvailability; +import com.intuit.tank.vm.agent.messages.AgentAvailabilityStatus; +import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; +import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; +import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; + +import java.io.InputStream; +import java.nio.charset.Charset; +import org.apache.commons.io.IOUtils; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -17,10 +41,21 @@ import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.Map; +import java.util.List; +import java.util.concurrent.TimeUnit; + @RestController @Tag(name = "Default") public class DefaultController { + private ScriptClient scriptClient; + private AgentClient agentClient; + private ProjectClient projectClient; + private DataFileClient dataFileClient; + @GetMapping(value ="/v2/ping", produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Pings Tank V2 API default service", summary = "Check if Tank V2 API is up") @ApiResponses(value = { @@ -30,4 +65,22 @@ public ResponseEntity ping() { return new ResponseEntity<>("PONG Tank V2 API", HttpStatus.OK); } + @GetMapping(value ="/v2/pong", produces = { MediaType.TEXT_PLAIN_VALUE } ) + public String pong() { + this.dataFileClient = new DataFileClient("http://localhost:8080/tank_war"); + +// String result = WebClient.create("http://localhost:8080/tank_war/api/v2/datafiles") +// .get() +// .uri(uriBuilder -> uriBuilder.path("/content") +// .queryParam("id", "24") +// .build()) +// .retrieve() +// .bodyToMono(String.class) +// .block(); + + + InputStream is = IOUtils.toInputStream(dataFileClient.getDatafileContent(24), StandardCharsets.UTF_8); + + return dataFileClient.getDatafileContent(24); + } } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ReportController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ReportController.java new file mode 100644 index 000000000..7deee9da3 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ReportController.java @@ -0,0 +1,41 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.controllers; + +import com.intuit.tank.rest.mvc.rest.services.report.ReportServiceV2; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import javax.annotation.Resource; +import java.io.IOException; + +@RestController +@RequestMapping(value = "/v2/report") +@Tag(name = "Report") +public class ReportController { + @Resource + private ReportServiceV2 reportServiceV2; + + @RequestMapping(value = "/{filename}", method = RequestMethod.GET) + @Operation(description = "Retrieves a specific log file from logs", summary = "Get streaming log file output", hidden = true) + public ResponseEntity downloadDatafile(@PathVariable String filename, @RequestParam(required = false) String from) throws IOException { + StreamingResponseBody response = reportServiceV2.getFile(filename, from); + + return ResponseEntity.ok() + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(response); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericServiceBadRequestException.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericServiceBadRequestException.java new file mode 100644 index 000000000..f96b1be24 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericServiceBadRequestException.java @@ -0,0 +1,42 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.controllers.errors; + +public class GenericServiceBadRequestException extends GenericServiceException { + + private static final long serialVersionUID = 1L; + + private final String service; + + private final String resource; + + + /** + * Construct with a message {@code String} that is returned by the inherited + * {@code Throwable.getMessage}. + * + * @param service + * the service impacted + * + * @param resource + * the specific service related resource + */ + public GenericServiceBadRequestException(String service, String resource) { + super("Bad request received for " + service + " service for " + resource); + this.service = service; + this.resource = resource; + } + + public String getService() { + return service; + } + + public String getResource() { + return resource; + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericServiceForbiddenAccessException.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericServiceForbiddenAccessException.java new file mode 100644 index 000000000..92a164050 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/errors/GenericServiceForbiddenAccessException.java @@ -0,0 +1,45 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.controllers.errors; + +public class GenericServiceForbiddenAccessException extends GenericServiceException { + + private static final long serialVersionUID = 1L; + + private final String service; + + private final String resource; + + + /** + * Construct with a message {@code String} that is returned by the inherited + * {@code Throwable.getMessage}. + * + * @param service + * the service impacted + * + * @param resource + * the specific service related resource + * @param cause + * the cause that is returned by the inherited + * {@code Throwable.getCause} + */ + public GenericServiceForbiddenAccessException(String service, String resource) { + super("Not authorize to access " + resource + " for " + service + " service"); + this.service = service; + this.resource = resource; + } + + public String getService() { + return service; + } + + public String getResource() { + return resource; + } +} 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 4801df63d..d922c917b 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 @@ -24,8 +24,8 @@ 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.ResponseUtil; +import com.intuit.tank.service.util.MessageSender; import com.intuit.tank.service.util.ServletInjector; import com.intuit.tank.vm.api.enumerated.ScriptDriver; import com.intuit.tank.vm.api.enumerated.TerminationPolicy; @@ -72,7 +72,7 @@ public ProjectContainer getAllProjects(){ @Override public Map getAllProjectNames(){ try { - List all = new ProjectDao().findAll(); + List all = new ProjectDao().findAllFast(); return all.stream().collect(Collectors.toMap(Project::getId, Project::getName)); } catch (Exception e) { LOGGER.error("Error returning all project names: " + e.getMessage(), e); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2.java new file mode 100644 index 000000000..846d9aa72 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2.java @@ -0,0 +1,39 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.services.report; + +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceBadRequestException; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceForbiddenAccessException; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; + +public interface ReportServiceV2 { + + /** + * Returns a specified log file + * + * @param filePath + * file path + * + * @param start + * starting line number + * + * @throws GenericServiceResourceNotFoundException + * if the file does not exist in logs + * + * @throws GenericServiceBadRequestException + * if file path is not a file + * + * @throws GenericServiceForbiddenAccessException + * if user not authorized to access file + * + * @return streaming output of log file + */ + public StreamingResponseBody getFile(String filePath, String start); + +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2Impl.java new file mode 100644 index 000000000..2fd724120 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2Impl.java @@ -0,0 +1,65 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.services.report; + +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceBadRequestException; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceForbiddenAccessException; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; +import com.intuit.tank.rest.mvc.rest.util.FileReader; + +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.io.File; +import java.nio.file.Paths; + +@Service +public class ReportServiceV2Impl implements ReportServiceV2 { + + @Autowired + private ServletContext servletContext; + + private static final Logger LOGGER = LogManager.getLogger(ReportServiceV2Impl.class); + + @Override + public StreamingResponseBody getFile(String filePath, String start) { + StreamingResponseBody streamingResponse; + start = start == null ? "0" : start; + try { + if (filePath.contains("..") || filePath.startsWith("/")) { + LOGGER.error("Error returning file: incorrect file path"); + throw new GenericServiceBadRequestException("report", "file path"); + } else { + String rootDir = "logs"; + final File f = new File(rootDir, filePath); + if (!f.exists()) { + LOGGER.error("Error returning file: file does not exist"); + throw new GenericServiceResourceNotFoundException("report", "file", null); + } else if (!f.isFile()) { + LOGGER.error("Error returning file: not a file"); + throw new GenericServiceBadRequestException("report", "file path"); + } else if (!f.canRead()) { + LOGGER.error("Error returning file: user not authorized to access file"); + throw new GenericServiceForbiddenAccessException("report", "file"); + } else { + long total = f.length(); + streamingResponse = FileReader.getFileStreamingResponseBody(f, total, start); + } + } + } catch (Exception e) { + LOGGER.error("Error returning file: file could not be found"); + throw new GenericServiceResourceNotFoundException("report", "file", null); + } + return streamingResponse; + } +} 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 4c639ab90..776f9a3a6 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 @@ -17,7 +17,7 @@ import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.models.scripts.*; -import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; +import com.intuit.tank.service.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptServiceUtil; import com.intuit.tank.script.processor.ScriptProcessor; import com.intuit.tank.service.util.MessageSender; diff --git a/rest-mvc/src/main/resources/application.yml b/rest-mvc/src/main/resources/application.yml index 8d7e4c8d0..7a9e4c421 100644 --- a/rest-mvc/src/main/resources/application.yml +++ b/rest-mvc/src/main/resources/application.yml @@ -1,6 +1,8 @@ spring: config: use-legacy-processing: true + codec: + max-in-memory-size: 200MB springdoc: swagger-ui: diff --git a/rest/service/common/pom.xml b/rest/service/common/pom.xml index 171dc5a67..5207dace6 100644 --- a/rest/service/common/pom.xml +++ b/rest/service/common/pom.xml @@ -25,6 +25,13 @@ org.glassfish.soteria javax.security.enterprise + + + org.springframework + spring-webmvc + 5.3.24 + + diff --git a/rest/service/common/src/main/java/com/intuit/tank/service/util/ResponseUtil.java b/rest/service/common/src/main/java/com/intuit/tank/service/util/ResponseUtil.java index f8fba6872..abd2283ff 100644 --- a/rest/service/common/src/main/java/com/intuit/tank/service/util/ResponseUtil.java +++ b/rest/service/common/src/main/java/com/intuit/tank/service/util/ResponseUtil.java @@ -29,7 +29,7 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; @@ -48,7 +48,7 @@ private ResponseUtil() { // empty private constructor to implement util pattern } - public static StreamingOutput getXMLStream(Object toMarshall) { + public static StreamingResponseBody getXMLStream(Object toMarshall) { return (OutputStream outputStream) -> { AWSXRay.beginSubsegment("JAXB.Marshal." + toMarshall.getClass().getSimpleName()); try { diff --git a/rest/service/project/src/main/java/com/intuit/tank/service/impl/v1/project/ProjectServiceV1.java b/rest/service/project/src/main/java/com/intuit/tank/service/impl/v1/project/ProjectServiceV1.java index 5ba3546a3..a4e2db3d2 100644 --- a/rest/service/project/src/main/java/com/intuit/tank/service/impl/v1/project/ProjectServiceV1.java +++ b/rest/service/project/src/main/java/com/intuit/tank/service/impl/v1/project/ProjectServiceV1.java @@ -178,7 +178,8 @@ public StreamingOutput getTestScriptForProject(Integer projectId) { throw new RuntimeException("Cannot find Project with id of " + projectId); } HDWorkload hdWorkload = ConverterUtil.convertWorkload(p.getWorkloads().get(0), p.getWorkloads().get(0).getJobConfiguration()); - return ResponseUtil.getXMLStream(hdWorkload); + StreamingOutput so = null; + return so; } /** @@ -206,7 +207,7 @@ public Response downloadTestScriptForProject(Integer projectId) { responseBuilder.header("Content-Disposition", "attachment; filename=\"" + filename + "\""); responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); HDWorkload hdWorkload = ConverterUtil.convertWorkload(p.getWorkloads().get(0), p.getWorkloads().get(0).getJobConfiguration()); - StreamingOutput so = ResponseUtil.getXMLStream(hdWorkload); + StreamingOutput so = null; responseBuilder.type(MediaType.APPLICATION_OCTET_STREAM_TYPE).entity(so); } else { responseBuilder = Response.noContent().status(Status.NOT_FOUND); diff --git a/rest/service/script/src/main/java/com/intuit/tank/service/impl/v1/script/ScriptServiceV1.java b/rest/service/script/src/main/java/com/intuit/tank/service/impl/v1/script/ScriptServiceV1.java index 95282ad43..bc8dd5eb8 100644 --- a/rest/service/script/src/main/java/com/intuit/tank/service/impl/v1/script/ScriptServiceV1.java +++ b/rest/service/script/src/main/java/com/intuit/tank/service/impl/v1/script/ScriptServiceV1.java @@ -364,7 +364,7 @@ public Response downloadHarnessScript(Integer scriptId) { responseBuilder.header("Content-Disposition", "attachment; filename=\"" + filename + "\""); responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); final HDWorkload hdWorkload = ConverterUtil.convertScriptToHdWorkload(script); - StreamingOutput so = ResponseUtil.getXMLStream(hdWorkload); + StreamingOutput so = null; responseBuilder.type(MediaType.APPLICATION_OCTET_STREAM_TYPE).entity(so); } else { responseBuilder = Response.noContent().status(Status.NOT_FOUND); @@ -385,7 +385,7 @@ public Response downloadScript(@Nonnull Integer id) { responseBuilder.header("Content-Disposition", "attachment; filename=\"" + filename + "\""); responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); final ScriptTO scriptTO = ScriptServiceUtil.scriptToTransferObject(script); - StreamingOutput so = ResponseUtil.getXMLStream(scriptTO); + StreamingOutput so = null; responseBuilder.type(MediaType.APPLICATION_OCTET_STREAM_TYPE).entity(so); } else { responseBuilder = Response.noContent().status(Status.NOT_FOUND); From 24c8ba59afd599192a7aaa3794bca77e0ca756d2 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 7 Apr 2023 09:41:11 -0700 Subject: [PATCH 12/73] fix: missing file --- proxy-parent/owasp-proxy/pom.xml | 5 + .../tank/rest/mvc/rest/util/FileReader.java | 105 ++++++++++++++++++ .../src/main/webapp/META-INF/context.xml | 13 +++ 3 files changed, 123 insertions(+) create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/FileReader.java diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml index 3299f5e5f..42064e1c8 100755 --- a/proxy-parent/owasp-proxy/pom.xml +++ b/proxy-parent/owasp-proxy/pom.xml @@ -96,6 +96,11 @@ 0.1.2 + + org.springframework + spring-dao + 2.0.8 + diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/FileReader.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/FileReader.java new file mode 100644 index 000000000..65d8b14a4 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/FileReader.java @@ -0,0 +1,105 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.util; + +import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.WritableByteChannel; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.List; + +/** + * FileServiceV1 + * + * @author dangleton + * + */ +public final class FileReader { + + private FileReader() { + // empty private constructor + } + + private static final Logger LOG = LogManager.getLogger(FileReader.class); + + /** + * Gets a StreamingResponseBody from the passed in file from start to end or from beginning to end if start is greater than + * end. if a negative number is passed, it will get the last n lines of the file. If 0 is passed it will return the + * entire file. + * + * @param f + * file + * + * @param total + * total number of lines + * + * @param start + * starting line number + * + * @return a StreamingResponseBody + */ + public static StreamingResponseBody getFileStreamingResponseBody(final File f, long total, String start) { + + long l = 0; + if (start != null) { + try { + l = Long.parseLong(start); + // num lines to get from end + if (l < 0) { + l = getStartChar(f, Math.abs(l), total); + } + } catch (Exception e) { + LOG.error("Error parsing start " + start + ": " + e); + } + } + final long to = l > total ? 0 : total; + final long from = l; + + StreamingResponseBody streamer = (final OutputStream output) -> { + try (FileChannel inputChannel = new FileInputStream(f).getChannel(); + WritableByteChannel outputChannel = Channels.newChannel(output)) { + inputChannel.transferTo(from, to, outputChannel); + } + // closing the channels + }; + LOG.debug("returning data from " + from + " - " + to + " of total " + total); + return streamer; + } + + /** + * @param f + * @param numLines + * @param total + * @return + * @throws IOException + */ + @SuppressWarnings({ "unchecked" }) + private static long getStartChar(File f, long numLines, long total) throws IOException { + List lines = FileUtils.readLines(f, StandardCharsets.UTF_8); + long count = 0; + if (lines.size() > numLines) { + Collections.reverse(lines); + for (int i = 0; i < numLines; i++) { + count += lines.get(i).length() + 1; + } + count = total - (count + 1); + } + return count; + } + +} diff --git a/web/web_ui/src/main/webapp/META-INF/context.xml b/web/web_ui/src/main/webapp/META-INF/context.xml index 6517d08d0..2fb659b00 100644 --- a/web/web_ui/src/main/webapp/META-INF/context.xml +++ b/web/web_ui/src/main/webapp/META-INF/context.xml @@ -5,5 +5,18 @@ auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> + From b84720fb8c0cd8ffc6909ab6cfe3ea47ac86ef5c Mon Sep 17 00:00:00 2001 From: zkofiro Date: Wed, 12 Apr 2023 20:11:27 -0700 Subject: [PATCH 13/73] moved last backend V1 deps over with models + tested locally --- .gitignore | 1 + rest-mvc/pom.xml | 23 +- .../mvc/rest/controllers/AgentController.java | 2 +- .../mvc/rest/controllers/JobController.java | 2 +- .../mvc/rest/models/common/CloudVmStatus.java | 346 ++++++++++++++++++ .../models/common/CloudVmStatusContainer.java | 207 +++++++++++ .../mvc/rest/models/common/Namespace.java | 31 ++ .../models/common/ProjectStatusContainer.java | 140 +++++++ .../mvc/rest/models/common/UserDetail.java | 86 +++++ .../rest/mvc/rest/models/common/VMStatus.java | 40 ++ .../rest/models/common/ValidationStatus.java | 225 ++++++++++++ .../rest/models/common/cloud/VMTracker.java | 111 ++++++ .../rest/services/agent/AgentServiceV2.java | 2 +- .../services/agent/AgentServiceV2Impl.java | 31 +- .../services/filters/FilterServiceV2Impl.java | 6 +- .../mvc/rest/services/jobs/JobServiceV2.java | 2 +- .../rest/services/jobs/JobServiceV2Impl.java | 31 +- .../projects/ProjectServiceV2Impl.java | 6 +- .../services/scripts/ScriptServiceV2Impl.java | 6 +- .../rest/mvc/rest/util/JobEventListener.java | 40 ++ .../rest/mvc/rest/util/JobEventSender.java | 315 ++++++++++++++++ .../mvc/rest/util/MessageEventSender.java | 29 ++ .../rest/mvc/rest/util/ServletInjector.java | 31 ++ .../src/main/resources/META-INF/beans.xml | 10 + rest-mvc/src/main/resources/application.yml | 2 +- .../rest/controllers/AgentControllerTest.java | 2 +- .../rest/controllers/JobControllerTest.java | 4 +- 27 files changed, 1681 insertions(+), 50 deletions(-) create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/MessageEventSender.java create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java create mode 100644 rest-mvc/src/main/resources/META-INF/beans.xml diff --git a/.gitignore b/.gitignore index 00a4a596d..d02b9abe0 100755 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ api/settings.xml agent/apiharness/settings.xml data_model/settings.xml data_access/settings.xml +rest-mvc/settings.xml wats_common/settings.xml wats_vmManager/settings.xml web/web_support/settings.xml diff --git a/rest-mvc/pom.xml b/rest-mvc/pom.xml index 63f745b4d..c289b87a1 100644 --- a/rest-mvc/pom.xml +++ b/rest-mvc/pom.xml @@ -26,9 +26,30 @@ org.springframework.boot spring-boot + + org.projectlombok + lombok + RELEASE + compile + + + ${project.groupId} + script-engine + ${project.version} + + + ${project.groupId} + data-access + ${project.version} + + + ${project.groupId} + tank-vm-manager + ${project.version} + ${project.groupId} - automation-service + tank-script-processor ${project.version} 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 e89b125b8..a6865bc06 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 @@ -7,7 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; 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; 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 5bf0541d2..e1bbc8113 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 @@ -7,7 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.services.jobs.JobServiceV2; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java new file mode 100644 index 000000000..5cbf2d484 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java @@ -0,0 +1,346 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.models.common; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import com.intuit.tank.vm.api.enumerated.JobStatus; +import com.intuit.tank.vm.api.enumerated.VMImageType; +import com.intuit.tank.vm.api.enumerated.VMRegion; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import javax.xml.bind.annotation.*; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * BrokerStatus + * + * @author dangleton + * + */ +@XmlRootElement(name = "cloudVm", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "CloudVm", namespace = Namespace.NAMESPACE_V1, propOrder = { + "instanceId", + "jobId", + "securityGroup", + "jobStatus", + "role", + "vmRegion", + "vmStatus", + "validationFailures", + "totalUsers", + "currentUsers", + "startTime", + "endTime", + "reportTime", + "totalTps", + "userDetails" +}) +public class CloudVmStatus implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "instanceId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private String instanceId; + + @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private String jobId; + + @XmlElement(name = "securityGroup", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private String securityGroup; + + @XmlElement(name = "jobStatus", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private JobStatus jobStatus = JobStatus.Unknown; + + @XmlElement(name = "role", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private VMImageType role = VMImageType.AGENT; + + @XmlElement(name = "vmRegion", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private VMRegion vmRegion; + + @XmlElement(name = "vmStatus", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private VMStatus vmStatus = VMStatus.unknown; + + @XmlElement(name = "validationFailures", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private ValidationStatus validationFailures; + + @XmlElement(name = "totalUsers", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int totalUsers; + + @XmlElement(name = "currentUsers", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int currentUsers; + + @XmlElement(name = "startTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private Date startTime; + + @XmlElement(name = "endTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private Date endTime; + + @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private Date reportTime; + + @XmlElement(name = "totalTps", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private int totalTps; + + @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) + @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private List userDetails = new ArrayList(); + + protected CloudVmStatus() { + } + + /** + * @param instanceId + * @param jobId + * @param securityGroup + * @param jobStatus + * @param vmStatus + * @param totalUsers + * @param currentUsers + */ + public CloudVmStatus(String instanceId, String jobId, String securityGroup, JobStatus jobStatus, VMImageType role, + VMRegion vmRegion, + VMStatus vmStatus, ValidationStatus validationFailures, + int totalUsers, int currentUsers, Date startTime, Date endTime) { + super(); + this.instanceId = instanceId; + this.jobId = jobId; + this.securityGroup = securityGroup; + this.vmRegion = vmRegion; + this.role = role; + this.jobStatus = jobStatus; + this.vmStatus = vmStatus; + this.validationFailures = validationFailures; + this.totalUsers = totalUsers; + this.currentUsers = currentUsers; + this.startTime = startTime; + this.endTime = endTime; + } + + /** + * + * @param copy + */ + public CloudVmStatus(CloudVmStatus copy) { + this.instanceId = copy.instanceId; + this.jobId = copy.jobId; + this.securityGroup = copy.securityGroup; + this.vmRegion = copy.vmRegion; + this.role = copy.role; + this.jobStatus = copy.jobStatus; + this.vmStatus = copy.vmStatus; + this.validationFailures = copy.validationFailures; + this.totalUsers = copy.totalUsers; + this.currentUsers = copy.currentUsers; + this.startTime = copy.startTime; + this.endTime = copy.endTime; + this.totalTps = copy.totalTps; + } + + /** + * @return the tpsInfo + */ + public int getTotalTps() { + return totalTps; + } + + /** + * @param totalTps + * the tpsInfo to set + */ + public void setTotalTps(int totalTps) { + this.totalTps = totalTps; + } + + /** + * @return the userDetails + */ + public List getUserDetails() { + return userDetails; + } + + /** + * @param userDetails + * the userDetails to set + */ + public void setUserDetails(List userDetails) { + this.userDetails = userDetails; + } + + /** + * @return the validationFailures + */ + public ValidationStatus getValidationFailures() { + return validationFailures; + } + + /** + * @return the instanceId + */ + public String getInstanceId() { + return instanceId; + } + + /** + * @return the vmRegion + */ + public VMRegion getVmRegion() { + return vmRegion; + } + + /** + * @return the jobId + */ + public String getJobId() { + return jobId; + } + + /** + * @return the securityGroup + */ + public String getSecurityGroup() { + return securityGroup; + } + + /** + * @return the jobStatus + */ + public JobStatus getJobStatus() { + return jobStatus; + } + + /** + * @return the vmStatus + */ + public VMStatus getVmStatus() { return vmStatus; } + + /** + * @return the totalUsers + */ + public int getTotalUsers() { + return totalUsers; + } + + /** + * @return the currentUsers + */ + public int getCurrentUsers() { + return currentUsers; + } + + /** + * @return the role + */ + public VMImageType getRole() { + return role; + } + + /** + * @return the startTime + */ + public Date getStartTime() { + return startTime; + } + + /** + * @return the endTime + */ + public Date getEndTime() { + return endTime; + } + + /** + * @return the reportTime + */ + public Date getReportTime() { + return reportTime; + } + + /** + * @param reportTime + * the reportTime to set + */ + public void setReportTime(Date reportTime) { + this.reportTime = reportTime; + } + + /** + * @param jobStatus + * the jobStatus to set + */ + public void setJobStatus(JobStatus jobStatus) { + this.jobStatus = jobStatus; + } + + /** + * @param vmStatus + * the vmStatus to set + */ + public void setVmStatus(VMStatus vmStatus) { + this.vmStatus = vmStatus; + } + + /** + * @param currentUsers + * the currentUsers to set + */ + public void setCurrentUsers(int currentUsers) { + this.currentUsers = currentUsers; + } + + /** + * @param endTime + * the endTime to set + */ + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CloudVmStatus)) { + return false; + } + CloudVmStatus o = (CloudVmStatus) obj; + return new EqualsBuilder().append(o.getInstanceId(), getInstanceId()).append(o.getJobId(), getJobId()) + .isEquals(); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder(29, 45).append(getInstanceId()).append(getJobId()).toHashCode(); + } + +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java new file mode 100644 index 000000000..a4b470299 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java @@ -0,0 +1,207 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.models.common; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import com.intuit.tank.vm.api.enumerated.JobQueueStatus; +import com.intuit.tank.vm.settings.TimeUtil; + +import javax.xml.bind.annotation.*; +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; + +/** + * BrokerStatus + * + * @author dangleton + * + */ +@XmlRootElement(name = "cloudVmContainer", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "CloudVmStatusContainer", namespace = Namespace.NAMESPACE_V1, propOrder = { + "statuses", + "status", + "startTime", + "endTime", + "reportTime", + "jobId", + "userDetails" +}) +public class CloudVmStatusContainer implements Serializable, Comparable { + + private static final long serialVersionUID = 1L; + + @XmlElementWrapper(name = "statuses", namespace = Namespace.NAMESPACE_V1) + @XmlElement(name = "status", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Set statuses = new HashSet(); + + @XmlElement(name = "status", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private JobQueueStatus status = JobQueueStatus.Created; + + @XmlElement(name = "startTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Date startTime = new Date(); + + @XmlElement(name = "endTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private Date endTime; + + @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Date reportTime = new Date(); + + @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private String jobId; + + @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) + @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private List userDetails = new ArrayList(); + + @XmlTransient + private Map> detailMap = new HashMap>(); + + /** + * @FrameworkUseOnly + */ + public CloudVmStatusContainer() { + } + + /** + * @param statuses + */ + public CloudVmStatusContainer(Set statuses) { + this.statuses = statuses; + } + + public JobQueueStatus getStatus() { + return status; + } + + public void setStatus(JobQueueStatus status) { + this.status = status; + } + + public void calculateUserDetails() { + List details; + Map map = new HashMap(); + for (CloudVmStatus status : statuses) { + for (UserDetail detail : status.getUserDetails()) { + Integer val = map.get(detail.getScript()); + if (val == null) { + val = 0; + } + map.put(detail.getScript(), val + detail.getUsers()); + } + } + details = map.entrySet().stream().map(entry -> new UserDetail(entry.getKey(), entry.getValue())).sorted().collect(Collectors.toList()); + userDetails = details; + detailMap.put(TimeUtil.normalizeToPeriod(15, new Date()), details); + } + + /** + * @return the detailMap + */ + public Map> getDetailMap() { + return detailMap; + } + + /** + * @return the statuses + */ + public Set getStatuses() { + return statuses; + } + + /** + * @return the startTime + */ + public Date getStartTime() { + return startTime; + } + + /** + * @param startTime + * the startTime to set + */ + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + /** + * @return the endTime + */ + public Date getEndTime() { + return endTime; + } + + /** + * @return the userDetails + */ + public List getUserDetails() { + return userDetails; + } + + /** + * @param endTime + * the endTime to set + */ + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + /** + * @return the reportTime + */ + public Date getReportTime() { + return reportTime; + } + + /** + * @param reportTime + * the reportTime to set + */ + public void setReportTime(Date reportTime) { + this.reportTime = reportTime; + } + + /** + * @return the jobId + */ + public String getJobId() { + return jobId; + } + + /** + * @param jobId + * the jobId to set + */ + public void setJobId(String jobId) { + this.jobId = jobId; + } + + /** + * {@inheritDoc} + */ + @Override + public int compareTo(CloudVmStatusContainer o) { + if (this.startTime != null) { + return this.startTime.compareTo(o.startTime); + } else if (o.startTime != null) { + return -1; + } + // both null + return 0; + } + +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java new file mode 100644 index 000000000..d92133dc7 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java @@ -0,0 +1,31 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.models.common; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +/** + * Namespace + * + * @author dangleton + * + */ +public class Namespace { + + public static final String NAMESPACE_V1 = "urn:wats/domain/cloud/v1"; + + private Namespace() { + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java new file mode 100644 index 000000000..85a5b3256 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java @@ -0,0 +1,140 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.models.common; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import com.intuit.tank.vm.settings.TimeUtil; + +import javax.xml.bind.annotation.*; +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; + +/** + * BrokerStatus + * + * @author dangleton + * + */ +@XmlRootElement(name = "projectStatusContainer", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ProjectStatusContainer", namespace = Namespace.NAMESPACE_V1, propOrder = { + "reportTime", + "jobId", + "userDetails" +}) +public class ProjectStatusContainer implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Date reportTime = new Date(); + + @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private String jobId; + + @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) + @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private List userDetails = null; + + @XmlTransient + private Map> detailMap = new HashMap>(); + + @XmlTransient + private Map containers = new HashMap(); + + /** + * @FrameworkUseOnly + */ + public ProjectStatusContainer() { + } + + public void addStatusContainer(CloudVmStatusContainer container) { + containers.put(container.getJobId(), container); + calculateUserDetails(); + } + + public void calculateUserDetails() { + List details; + Map map = new HashMap(); + long oldTime = System.currentTimeMillis() - 120000;// 2 minutes + Set toRemove = new HashSet(); + for (CloudVmStatusContainer container : containers.values()) { + if (container.getReportTime().getTime() < oldTime) { + toRemove.add(container.getJobId()); + } else { + for (UserDetail detail : container.getUserDetails()) { + Integer val = map.get(detail.getScript()); + if (val == null) { + val = 0; + } + map.put(detail.getScript(), val + detail.getUsers()); + } + } + } + details = map.entrySet().stream().map(entry -> new UserDetail(entry.getKey(), entry.getValue())).sorted().collect(Collectors.toList()); + userDetails = details; + detailMap.put(TimeUtil.normalizeToPeriod(15, new Date()), details); + for (String s : toRemove) { + containers.remove(s); + } + } + + /** + * @return the detailMap + */ + public Map> getDetailMap() { + return detailMap; + } + + /** + * @return the userDetails + */ + public List getUserDetails() { + return userDetails; + } + + /** + * @return the reportTime + */ + public Date getReportTime() { + return reportTime; + } + + /** + * @param reportTime + * the reportTime to set + */ + public void setReportTime(Date reportTime) { + this.reportTime = reportTime; + } + + /** + * @return the jobId + */ + public String getJobId() { + return jobId; + } + + /** + * @param jobId + * the jobId to set + */ + public void setJobId(String jobId) { + this.jobId = jobId; + } + +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java new file mode 100644 index 000000000..f4be033a2 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java @@ -0,0 +1,86 @@ +package com.intuit.tank.rest.mvc.rest.models.common; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import org.apache.commons.lang3.builder.ToStringBuilder; + +import javax.xml.bind.annotation.*; +import java.io.Serializable; +import java.util.Date; + +@XmlRootElement(name = "UserDetail", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "UserDetail", namespace = Namespace.NAMESPACE_V1) +public class UserDetail implements Serializable, Comparable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "script", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private String script; + + @XmlElement(name = "users", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Integer users; + + @XmlElement(name = "created", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Date createTime; + + /** + * @{frameworkUseOnly + */ + public UserDetail() { + + } + + public UserDetail(String script, Integer users) { + super(); + this.script = script; + this.users = users; + this.createTime = new Date(); + } + + /** + * @return the script + */ + public String getScript() { + return script; + } + + /** + * @return the users + */ + public Integer getUsers() { + return users; + } + + /** + * @return the createTime + */ + public Date getCreateTime() { + return createTime; + } + + @Override + public int compareTo(UserDetail o) { + return script.compareTo(o.script); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java new file mode 100644 index 000000000..dfcc7137c --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java @@ -0,0 +1,40 @@ +package com.intuit.tank.rest.mvc.rest.models.common; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.io.Serializable; + +public enum VMStatus implements Serializable { + unknown, + starting, + pending, + rampPaused, + rebooting, + running, + stopping, + stopped, + shutting_down, + terminated; + + public static final VMStatus fromString(String value) { + VMStatus ret = null; + if ("shutting-down".equals(value)) { + ret = VMStatus.shutting_down; + } else { + ret = VMStatus.valueOf(value); + } + return ret != null ? ret : VMStatus.unknown; + } + +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java new file mode 100644 index 000000000..9c01504e2 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java @@ -0,0 +1,225 @@ +/** + * Copyright 2013 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.models.common; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import javax.xml.bind.annotation.*; +import java.io.Serializable; + +/** + * ValidationStatus + * + * @author psadikov + * + */ +@XmlRootElement(name = "validationCloudVm", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "validationCloudVm", namespace = Namespace.NAMESPACE_V1, propOrder = { + "kills", + "aborts", + "gotos", + "skips", + "skipGroups", + "restarts" +}) +public class ValidationStatus implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "kills", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int kills; + + @XmlElement(name = "aborts", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int aborts; + + @XmlElement(name = "gotos", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int gotos; + + @XmlElement(name = "skips", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int skips; + + @XmlElement(name = "skipGroups", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int skipGroups; + + @XmlElement(name = "restarts", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int restarts; + + public ValidationStatus() { + } + + /** + * + */ + public ValidationStatus(int kills, int aborts, int gotos, int skips, int skipGroups, int restarts) { + super(); + this.kills = kills; + this.aborts = aborts; + this.gotos = gotos; + this.skips = skips; + this.skipGroups = skipGroups; + this.restarts = restarts; + } + + /** + * @return total number of failures + */ + public int getTotal() { + return kills + aborts + gotos + skips + skipGroups + restarts; + } + + /** + * @return the validationKills + */ + public int getValidationKills() { + return kills; + } + + /** + * @return the validationAborts + */ + public int getValidationAborts() { + return aborts; + } + + /** + * @return the validationGotos + */ + public int getValidationGotos() { + return gotos; + } + + /** + * @return the validationSkips + */ + public int getValidationSkips() { + return skips; + } + + /** + * @return the validationSkipGroups + */ + public int getValidationSkipGroups() { + return skipGroups; + } + + /** + * @return the validationRestarts + */ + public int getValidationRestarts() { + return restarts; + } + + /** + * Add fail counts from another ValidationStatus + */ + public void addFailures(ValidationStatus other) { + this.kills += other.kills; + this.aborts += other.aborts; + this.gotos += other.gotos; + this.skips += other.skips; + this.skipGroups += other.skipGroups; + this.restarts += other.restarts; + } + + /** + * Update kill count + */ + public void addKill() { + kills++; + } + + /** + * Update abort count + */ + public void addAbort() { + aborts++; + } + + /** + * Update goto count + */ + public void addGoto() { + gotos++; + } + + /** + * Update skip count + */ + public void addSkip() { + skips++; + } + + /** + * Update skip group count + */ + public void addSkipGroup() { + skipGroups++; + } + + /** + * Update restart count + */ + public void addRestart() { + restarts++; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ValidationStatus)) { + return false; + } + ValidationStatus o = (ValidationStatus) obj; + return new EqualsBuilder() + .append(o.getValidationKills(), getValidationKills()) + .append(o.getValidationAborts(), getValidationAborts()) + .append(o.getValidationGotos(), getValidationGotos()) + .append(o.getValidationSkips(), getValidationSkips()) + .append(o.getValidationSkipGroups(), getValidationSkipGroups()) + .append(o.getValidationRestarts(), getValidationRestarts()) + .isEquals(); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder(29, 37) + .append(getValidationKills()) + .append(getValidationAborts()) + .append(getValidationGotos()) + .append(getValidationSkips()) + .append(getValidationSkipGroups()) + .append(getValidationRestarts()) + .toHashCode(); + } + +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java new file mode 100644 index 000000000..b5712a7d6 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java @@ -0,0 +1,111 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.rest.mvc.rest.models.common.cloud; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; +import com.intuit.tank.rest.mvc.rest.models.common.ProjectStatusContainer; +import com.intuit.tank.vm.event.JobEvent; +import org.springframework.stereotype.Component; + +import javax.annotation.Nonnull; +import java.util.Set; + +@Component +public interface VMTracker { + + /** + * + * @param projectId + * @return + */ + public ProjectStatusContainer getProjectStatusContainer(String projectId); + + /** + * + * @param event + * the event to publish + */ + public void publishEvent(JobEvent event); + + /** + * Gets the Status of the instance. + * + * @param instanceId + * the instance id to get the status for + * @return the status or null + */ + public CloudVmStatus getStatus(@Nonnull String instanceId); + + /** + * Sets the status of the specified instance. + * + * @param status + * the status to set to + */ + public void setStatus(@Nonnull CloudVmStatus status); + + /** + * @param jobId + * the id of the job to get the vmstatuses for. + * @return the container with all the statuses. + */ + public CloudVmStatusContainer getVmStatusForJob(String jobId); + + /** + * Tests if we are in dev mode for killing of instances sample data. + * + * @return + */ + public boolean isDevMode(); + + /** + * Remove the specified instance of a job. + * + * @param instanceId + * the instance of the jkob to remove + */ + public void removeStatusForInstance(String instanceId); + + /** + * Removes the Statuses for the specified job Id + * + * @param jobId + * the job to remove + */ + public void removeStatusForJob(String jobId); + + /** + * + * @return + */ + public Set getAllJobs(); + + /** + * @param id + * the job id + */ + public boolean isRunning(String id); + + /** + * + * @param id + * the job Id + */ + public void stopJob(String id); + +} \ No newline at end of file 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 a874e9011..a2f2df39e 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 @@ -7,8 +7,8 @@ */ package com.intuit.tank.rest.mvc.rest.services.agent; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; 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; 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 5f60c6fe4..d11370fa4 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 @@ -7,15 +7,14 @@ */ package com.intuit.tank.rest.mvc.rest.services.agent; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.perfManager.workLoads.JobManager; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; -import com.intuit.tank.service.impl.v1.cloud.JobController; -import com.intuit.tank.service.impl.v1.cloud.CloudController; -import com.intuit.tank.service.util.ServletInjector; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.util.JobEventSender; +import com.intuit.tank.rest.mvc.rest.util.ServletInjector; import com.intuit.tank.storage.FileData; import com.intuit.tank.storage.FileStorage; import com.intuit.tank.storage.FileStorageFactory; @@ -202,8 +201,8 @@ public void setStandaloneAgentAvailability(AgentAvailability availability) { public CloudVmStatus getInstanceStatus(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { - CloudController controller = new ServletInjector().getManagedBean( - servletContext, CloudController.class); + JobEventSender controller = new ServletInjector().getManagedBean( + servletContext, JobEventSender.class); return controller.getVmStatus(instanceId); } catch (Exception e) { LOGGER.error("Error returning instance status: " + e.getMessage(), e); @@ -220,8 +219,8 @@ public void setInstanceStatus(String instanceId, CloudVmStatus status) { segment.putAnnotation("TotalUsers", status.getTotalUsers()); segment.putAnnotation("totalTps", status.getTotalTps()); try { - CloudController controller = new ServletInjector().getManagedBean( - servletContext, CloudController.class); + JobEventSender controller = new ServletInjector().getManagedBean( + servletContext, JobEventSender.class); controller.setVmStatus(instanceId, status); } catch (Exception e) { LOGGER.error("Error updating instance status: " + e.getMessage(), e); @@ -233,8 +232,8 @@ public void setInstanceStatus(String instanceId, CloudVmStatus status) { public String stopInstance(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean( + servletContext, JobEventSender.class); controller.stopAgent(instanceId); return getInstanceStatus(instanceId).getVmStatus().name(); } catch (Exception e) { @@ -247,8 +246,8 @@ public String stopInstance(String instanceId) { public String pauseInstance(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean( + servletContext, JobEventSender.class); controller.pauseRampInstance(instanceId); return getInstanceStatus(instanceId).getVmStatus().name(); } catch (Exception e) { @@ -261,8 +260,8 @@ public String pauseInstance(String instanceId) { public String resumeInstance(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean( + servletContext, JobEventSender.class); controller.resumeRampInstance(instanceId); return getInstanceStatus(instanceId).getVmStatus().name(); } catch (Exception e) { @@ -275,8 +274,8 @@ public String resumeInstance(String instanceId) { public String killInstance(String instanceId) { AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); try { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean( + servletContext, JobEventSender.class); controller.killInstance(instanceId); return getInstanceStatus(instanceId).getVmStatus().name(); } catch (Exception e) { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java index 4a110e170..553e3b939 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java @@ -25,8 +25,8 @@ import com.intuit.tank.rest.mvc.rest.models.filters.ApplyFiltersRequest; import com.intuit.tank.rest.mvc.rest.util.FilterServiceUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptFilterUtil; -import com.intuit.tank.service.impl.v1.automation.MessageSender; -import com.intuit.tank.service.util.ServletInjector; +import com.intuit.tank.rest.mvc.rest.util.MessageEventSender; +import com.intuit.tank.rest.mvc.rest.util.ServletInjector; import com.intuit.tank.vm.settings.ModifiedEntityMessage; import com.intuit.tank.vm.settings.ModificationType; @@ -139,7 +139,7 @@ public String applyFilters(Integer scriptId, ApplyFiltersRequest request) { return null; } private void sendMsg(BaseEntity entity, ModificationType type) { - MessageSender sender = new ServletInjector().getManagedBean(servletContext, MessageSender.class); + MessageEventSender sender = new ServletInjector().getManagedBean(servletContext, MessageEventSender.class); sender.sendEvent(new ModifiedEntityMessage(entity.getClass(), entity.getId(), type)); } 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 3b98205d4..68835fc57 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 @@ -7,9 +7,9 @@ */ package com.intuit.tank.rest.mvc.rest.services.jobs; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; 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 0486997be..a38581a4b 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.model.v1.cloud.CloudVmStatusContainer; import com.intuit.tank.dao.BaseDao; import com.intuit.tank.dao.DataFileDao; import com.intuit.tank.dao.JobInstanceDao; @@ -29,6 +28,7 @@ import com.intuit.tank.project.Workload; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; @@ -37,9 +37,8 @@ import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.JobDetailFormatter; import com.intuit.tank.rest.mvc.rest.util.JobValidator; -import com.intuit.tank.service.impl.v1.cloud.CloudController; -import com.intuit.tank.service.impl.v1.cloud.JobController; -import com.intuit.tank.service.util.ServletInjector; +import com.intuit.tank.rest.mvc.rest.util.JobEventSender; +import com.intuit.tank.rest.mvc.rest.util.ServletInjector; import com.intuit.tank.util.TestParamUtil; import com.intuit.tank.util.TestParameterContainer; import com.intuit.tank.util.CreateDateComparator; @@ -164,8 +163,8 @@ public String getJobStatus(Integer jobId){ @Override public CloudVmStatusContainer getJobVMStatus(String jobId){ try { - CloudController controller = new ServletInjector().getManagedBean( - servletContext, CloudController.class); + JobEventSender controller = new ServletInjector().getManagedBean( + servletContext, JobEventSender.class); return controller.getVmStatusForJob(jobId); } catch (Exception e) { LOGGER.error("Error returning Job Instance Status: " + e.getMessage(), e); @@ -200,8 +199,8 @@ public List> getAllJobStatus(){ public String startJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { - JobController controller = new ServletInjector().getManagedBean(servletContext, - JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean(servletContext, + JobEventSender.class); controller.startJob(Integer.toString(jobId)); return getJobStatus(jobId); } catch (Exception e) { @@ -214,8 +213,8 @@ public String startJob(Integer jobId) { public String stopJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { - JobController controller = new ServletInjector().getManagedBean(servletContext, - JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean(servletContext, + JobEventSender.class); controller.stopJob(Integer.toString(jobId)); return getJobStatus(jobId); } catch (Exception e) { @@ -228,8 +227,8 @@ public String stopJob(Integer jobId) { public String pauseJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { - JobController controller = new ServletInjector().getManagedBean(servletContext, - JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean(servletContext, + JobEventSender.class); controller.pauseRampJob(Integer.toString(jobId)); return getJobStatus(jobId); } catch (Exception e) { @@ -242,8 +241,8 @@ public String pauseJob(Integer jobId) { public String resumeJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { - JobController controller = new ServletInjector().getManagedBean(servletContext, - JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean(servletContext, + JobEventSender.class); controller.resumeRampJob(Integer.toString(jobId)); return getJobStatus(jobId); } catch (Exception e) { @@ -256,8 +255,8 @@ public String resumeJob(Integer jobId) { public String killJob(Integer jobId) { AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); try { - JobController controller = new ServletInjector().getManagedBean(servletContext, - JobController.class); + JobEventSender controller = new ServletInjector().getManagedBean(servletContext, + JobEventSender.class); controller.killJob(Integer.toString(jobId)); return getJobStatus(jobId); } catch (Exception e) { 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 4801df63d..26026aee2 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 @@ -25,8 +25,8 @@ 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.rest.mvc.rest.util.MessageEventSender; +import com.intuit.tank.rest.mvc.rest.util.ServletInjector; import com.intuit.tank.vm.api.enumerated.ScriptDriver; import com.intuit.tank.vm.api.enumerated.TerminationPolicy; import com.intuit.tank.vm.common.TankConstants; @@ -171,7 +171,7 @@ private synchronized Project createOrUpdateProject(Integer projectId, Automation } private void sendMsg(BaseEntity entity, ModificationType type) { - MessageSender sender = new ServletInjector().getManagedBean(servletContext, MessageSender.class); + MessageEventSender sender = new ServletInjector().getManagedBean(servletContext, MessageEventSender.class); sender.sendEvent(new ModifiedEntityMessage(entity.getClass(), entity.getId(), type)); } 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 7933e504e..b67132051 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 @@ -20,8 +20,8 @@ import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptServiceUtil; import com.intuit.tank.script.processor.ScriptProcessor; -import com.intuit.tank.service.impl.v1.automation.MessageSender; -import com.intuit.tank.service.util.ServletInjector; +import com.intuit.tank.rest.mvc.rest.util.MessageEventSender; +import com.intuit.tank.rest.mvc.rest.util.ServletInjector; import com.intuit.tank.transform.scriptGenerator.ConverterUtil; import com.intuit.tank.vm.settings.ModifiedEntityMessage; import com.intuit.tank.vm.settings.ModificationType; @@ -294,7 +294,7 @@ public Map uploadProxyScript(String name, Integer scriptId, Stri } private void sendMsg(BaseEntity entity, ModificationType type) { - MessageSender sender = new ServletInjector().getManagedBean(servletContext, MessageSender.class); + MessageEventSender sender = new ServletInjector().getManagedBean(servletContext, MessageEventSender.class); sender.sendEvent(new ModifiedEntityMessage(entity.getClass(), entity.getId(), type)); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java new file mode 100644 index 000000000..feb82735a --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java @@ -0,0 +1,40 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.util; + +import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; +import com.intuit.tank.vm.event.JobEvent; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.web.context.annotation.ApplicationScope; +import org.springframework.context.event.EventListener; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import java.io.Serializable; + +@Service +@ApplicationScope +public class JobEventListener implements Serializable { + + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LogManager.getLogger(JobEventListener.class); + + @Autowired + private ObjectProvider controllerSource; + + @EventListener + public void observerJobKillRequest(JobEvent request) { + LOG.info("Got Job Event: " + request); + if (request.getEvent() == JobLifecycleEvent.JOB_ABORTED) { + controllerSource.getIfAvailable().killJob(request.getJobId(), false); + } + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java new file mode 100644 index 000000000..242e26c3a --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java @@ -0,0 +1,315 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.util; + +import com.intuit.tank.dao.JobInstanceDao; +import com.intuit.tank.dao.WorkloadDao; +import com.intuit.tank.dao.util.ProjectDaoUtil; +import com.intuit.tank.harness.data.HDWorkload; +import com.intuit.tank.perfManager.workLoads.JobManager; +import com.intuit.tank.project.JobInstance; +import com.intuit.tank.project.Workload; +import com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTracker; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; +import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; +import com.intuit.tank.transform.scriptGenerator.ConverterUtil; +import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; +import com.intuit.tank.vm.api.enumerated.JobQueueStatus; +import com.intuit.tank.vm.api.enumerated.JobStatus; +import com.intuit.tank.vm.api.enumerated.VMRegion; +import com.intuit.tank.vm.event.JobEvent; +import com.intuit.tank.vm.perfManager.AgentChannel; +import com.intuit.tank.vm.settings.TankConfig; +import com.intuit.tank.vm.vmManager.VMTerminator; +import com.intuit.tank.vmManager.environment.amazon.AmazonInstance; + +import com.amazonaws.xray.AWSXRay; +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.context.annotation.RequestScope; +import org.springframework.stereotype.Service; +import javax.enterprise.event.Event; +import java.util.*; +import java.util.stream.Collectors; + +@Service +@RequestScope +public class JobEventSender { + + private static final Logger LOG = LogManager.getLogger(JobEventSender.class); + + @Autowired + private VMTracker vmTracker; + + @Autowired + private VMTerminator terminator; + + @Autowired + private JobManager jobManager; + + @Autowired + private AgentChannel agentChannel; + + @Autowired + private Event jobEventProducer; + + public String startJob(String jobId) { + AWSXRay.beginSubsegment("Start.Job." + jobId); + JobInstanceDao jobInstanceDao = new JobInstanceDao(); + JobInstance job = jobInstanceDao.findById(Integer.valueOf(jobId)); + synchronized (jobId) { + if (job.getStatus() == JobQueueStatus.Created) {// only start if new job + // save the job + job.setStatus(JobQueueStatus.Starting); + jobInstanceDao.saveOrUpdate(job); + + ProjectDaoUtil.storeScriptFile(jobId, getScriptString(job)); + + vmTracker.removeStatusForJob(jobId); + jobManager.startJob(job.getId()); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STARTED)); + } + } + AWSXRay.endSubsegment(); + return jobId; + } + + /** + * Use the AWS SDK to terminate instances. + * If no instances can be found, set jobStatus to Completed + */ + public void killJob(String jobId, boolean fireEvent) { + List instanceIds = getInstancesForJob(jobId); + vmTracker.stopJob(jobId); + if (instanceIds.isEmpty()) { + JobInstanceDao dao = new JobInstanceDao(); + JobInstance job = dao.findById(Integer.parseInt(jobId)); + if (job != null) { + job.setStatus(JobQueueStatus.Completed); + job.setEndTime(new Date()); + dao.saveOrUpdate(job); + } + } else { + killInstances(instanceIds); + } + + if (fireEvent) { + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_KILLED)); + } + } + + public void killJob(String jobId) { + killJob(jobId, true); + } + + public Set killAllJobs() { + Set jobs = vmTracker.getAllJobs(); + for (CloudVmStatusContainer job : jobs) { + String jobId = job.getJobId(); + killJob(jobId, true); + } + return jobs; + } + + public void killInstance(String instanceId) { killInstances(Collections.singletonList(instanceId)); } + + public void killInstances(List instanceIds) { + agentChannel.killAgents(instanceIds); + + if (!vmTracker.isDevMode()) { + for (VMRegion region : new TankConfig().getVmManagerConfig().getRegions()) { + AmazonInstance amzInstance = new AmazonInstance(region); + amzInstance.killInstances(instanceIds); + } + } + String jobId = null; + for (String instanceId : instanceIds) { + CloudVmStatus status = new CloudVmStatus(vmTracker.getStatus(instanceId)); + status.setCurrentUsers(0); + status.setEndTime(new Date()); + status.setJobStatus(JobStatus.Completed); + status.setVmStatus(VMStatus.terminated); + vmTracker.setStatus(status); + jobId = status.getJobId(); + } + if (jobId != null) { + checkJobStatus(jobId); + } + } + + public Set stopAllJobs() { + Set jobs = vmTracker.getAllJobs(); + for (CloudVmStatusContainer job : jobs) { + String jobId = (job).getJobId(); + List instanceIds = getInstancesForJob(jobId); + vmTracker.stopJob(jobId); + stopAgents(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STOPPED)); + } + return jobs; + } + + public void stopJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + vmTracker.stopJob(jobId); + stopAgents(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STOPPED)); + } + + public void stopAgent(String instanceId) { + stopAgents(Collections.singletonList(instanceId)); + + } + + public void stopAgents(List instanceIds) { + agentChannel.stopAgents(instanceIds); + } + + public void pauseJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + pauseAgents(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_PAUSED)); + } + + public void pauseAgent(String instanceId) { + pauseAgents(Collections.singletonList(instanceId)); + } + + public void pauseAgents(List instanceIds) { + agentChannel.pauseAgents(instanceIds); + } + + public void restartJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + restartAgents(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_RESUMED)); + } + + public void restartAgent(String instanceId) { + restartAgents(Collections.singletonList(instanceId)); + } + + public void restartAgents(List instanceIds) { + agentChannel.restartAgents(instanceIds); + } + + public void pauseRampInstance(String instanceId) { + pauseRampInstances(Collections.singletonList(instanceId)); + } + + public void pauseRampJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + pauseRampInstances(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.RAMP_PAUSED)); + } + + public void pauseRampInstances(List instanceIds) { + agentChannel.pauseRamp(instanceIds); + } + + public void resumeRampInstance(String instanceId) { + resumeRampInstances(Collections.singletonList(instanceId)); + } + + public void resumeRampJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + resumeRampInstances(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.RAMP_RESUMED)); + } + + public void resumeRampInstances(List instanceIds) { + agentChannel.resumeRamp(instanceIds); + } + + private List getInstancesForJob(String jobId) { + List instanceIds = new ArrayList(); + CloudVmStatusContainer statuses = vmTracker.getVmStatusForJob(jobId); + if (statuses != null) { + instanceIds = statuses.getStatuses().stream().map(CloudVmStatus::getInstanceId).collect(Collectors.toList()); + } + return instanceIds; + } + + // Agent/VM Status Methods + + public CloudVmStatus getVmStatus(String instanceId) { + return vmTracker.getStatus(instanceId); + } + + public void setVmStatus(final String instanceId, final CloudVmStatus status) { + vmTracker.setStatus(status); + if (status.getJobStatus() == JobStatus.Completed || status.getVmStatus() == VMStatus.terminated) { + // will terrminate instance after waiting for some cleanup time + terminator.terminate(status.getInstanceId()); + // check job status and kill off instances appropriately + checkJobStatus(status.getJobId()); + } + } + + public CloudVmStatusContainer getVmStatusForJob(String jobId) { + return vmTracker.getVmStatusForJob(jobId); + } + + public void checkJobStatus(String jobId) { + CloudVmStatusContainer container = vmTracker.getVmStatusForJob(jobId); + LOG.info("Checking Job Status to see if we can kill reporting instances. Container=" + container); + if (container != null) { + if (container.getEndTime() != null) { + JobInstanceDao dao = new JobInstanceDao(); + // hack to see if this is an automatino job + + // set the status of the JobInstance to finished. + JobInstance finishedJob = dao.findById(Integer.valueOf(jobId)); + if (finishedJob.getEndTime() == null) { + finishedJob.setEndTime(new Date()); + finishedJob.setStatus(JobQueueStatus.Completed); + dao.saveOrUpdate(finishedJob); + } + List statuses = Arrays.asList(JobQueueStatus.Running,JobQueueStatus.Starting ); + List instances = dao.getForStatus(statuses); + LOG.info("Checking Job Status to see if we can kill reporting instances. found running instances: " + + instances.size()); + boolean killModal = true; + boolean killNonRegional = true; + + for (JobInstance job : instances) { + CloudVmStatusContainer statusForJob = vmTracker.getVmStatusForJob(Integer.toString(job.getId())); + if (!jobId.equals(Integer.toString(job.getId())) && statusForJob != null + && statusForJob.getEndTime() == null) { + LOG.info("Found another job that is not finished: " + job); + } + } + if (killNonRegional || killModal) { + for (CloudVmStatusContainer statusForJob : vmTracker.getAllJobs()) { + if (statusForJob.getEndTime() == null && !NumberUtils.isCreatable(statusForJob.getJobId())) { + killNonRegional = false; + killModal = false; + LOG.info("Cannot kill Reporting instances because of automation job id: " + + statusForJob.getJobId()); + } + } + } + } else { + LOG.info("Container does not have end time set so cannot kill reporting instances."); + } + } + + } + + public static String getScriptString(JobInstance job) { + WorkloadDao dao = new WorkloadDao(); + Workload workload = dao.findById(job.getWorkloadId()); + workload.getTestPlans(); + dao.loadScriptsForWorkload(workload); + HDWorkload hdWorkload = ConverterUtil.convertWorkload(workload, job); + return ConverterUtil.getWorkloadXML(hdWorkload); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/MessageEventSender.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/MessageEventSender.java new file mode 100644 index 000000000..2ed6156ad --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/MessageEventSender.java @@ -0,0 +1,29 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.util; + +import com.intuit.tank.vm.settings.ModifiedEntityMessage; + +import javax.annotation.Nonnull; +import javax.enterprise.event.Event; +import javax.inject.Inject; + +public class MessageEventSender { + + @Inject + private Event eventSender; + + /** + * Fires the specified event + * + * @param msg + */ + public void sendEvent(@Nonnull ModifiedEntityMessage msg) { + eventSender.fire(msg); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java new file mode 100644 index 000000000..ca31b48eb --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java @@ -0,0 +1,31 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.util; + +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import org.springframework.stereotype.Service; +import javax.servlet.ServletContext; + +@Service +public class ServletInjector { + + private BeanManager getBeanManager(ServletContext servletContext) { + return (BeanManager) servletContext + .getAttribute("org.jboss.weld.environment.servlet.javax.enterprise.inject.spi.BeanManager"); + } + + @SuppressWarnings({ "unchecked" }) + public T getManagedBean(ServletContext servletContext, Class beanClass) { + BeanManager beanManager = getBeanManager(servletContext); + Bean bean = beanManager.getBeans(beanClass).iterator().next(); + CreationalContext cc = beanManager.createCreationalContext(bean); + return (T) beanManager.getReference(bean, beanClass, cc); + } +} diff --git a/rest-mvc/src/main/resources/META-INF/beans.xml b/rest-mvc/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..16ab4cdff --- /dev/null +++ b/rest-mvc/src/main/resources/META-INF/beans.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/rest-mvc/src/main/resources/application.yml b/rest-mvc/src/main/resources/application.yml index 8d7e4c8d0..6b2988455 100644 --- a/rest-mvc/src/main/resources/application.yml +++ b/rest-mvc/src/main/resources/application.yml @@ -15,7 +15,7 @@ jsk: server: max-http-header-size: 32KB port: 8080 - include-debug-info: false # Set to true for debug logs in error messages + include-debug-info: true # Set to true for stack trace in error log messages error: whitelabel: enabled: false diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java index 898a0a70b..c38f42105 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java @@ -7,10 +7,10 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.rest.mvc.rest.services.agent.AgentServiceV2; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentAvailabilityStatus; import com.intuit.tank.vm.agent.messages.AgentData; diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java index 09f092425..e5dc3b338 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java @@ -7,9 +7,9 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.rest.mvc.rest.services.jobs.JobServiceV2; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; From b2a0e7ae79cb8e3f4db592658d6e736a1ebb8a40 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Wed, 12 Apr 2023 20:16:25 -0700 Subject: [PATCH 14/73] updating file documentation --- .../mvc/rest/models/common/CloudVmStatus.java | 24 ++++------------- .../models/common/CloudVmStatusContainer.java | 25 ++++------------- .../mvc/rest/models/common/Namespace.java | 27 +++++-------------- .../models/common/ProjectStatusContainer.java | 24 ++++------------- .../mvc/rest/models/common/UserDetail.java | 20 +++++--------- .../rest/mvc/rest/models/common/VMStatus.java | 20 +++++--------- .../rest/models/common/ValidationStatus.java | 25 ++++------------- .../rest/models/common/cloud/VMTracker.java | 19 ++++--------- 8 files changed, 45 insertions(+), 139 deletions(-) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java index 5cbf2d484..d610fd7d9 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java @@ -1,20 +1,12 @@ /** - * Copyright 2011 Intuit Inc. All Rights Reserved + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ package com.intuit.tank.rest.mvc.rest.models.common; -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.api.enumerated.VMImageType; @@ -29,12 +21,6 @@ import java.util.Date; import java.util.List; -/** - * BrokerStatus - * - * @author dangleton - * - */ @XmlRootElement(name = "cloudVm", namespace = Namespace.NAMESPACE_V1) @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "CloudVm", namespace = Namespace.NAMESPACE_V1, propOrder = { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java index a4b470299..428132fe3 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java @@ -1,21 +1,12 @@ /** - * Copyright 2011 Intuit Inc. All Rights Reserved + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ package com.intuit.tank.rest.mvc.rest.models.common; -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - import com.intuit.tank.vm.api.enumerated.JobQueueStatus; import com.intuit.tank.vm.settings.TimeUtil; @@ -24,12 +15,6 @@ import java.util.*; import java.util.stream.Collectors; -/** - * BrokerStatus - * - * @author dangleton - * - */ @XmlRootElement(name = "cloudVmContainer", namespace = Namespace.NAMESPACE_V1) @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "CloudVmStatusContainer", namespace = Namespace.NAMESPACE_V1, propOrder = { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java index d92133dc7..d5515be9f 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java @@ -1,30 +1,15 @@ /** - * Copyright 2011 Intuit Inc. All Rights Reserved + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ package com.intuit.tank.rest.mvc.rest.models.common; -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -/** - * Namespace - * - * @author dangleton - * - */ public class Namespace { - public static final String NAMESPACE_V1 = "urn:wats/domain/cloud/v1"; + public static final String NAMESPACE_V1 = "urn:tank/domain/agent/v2"; private Namespace() { } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java index 85a5b3256..2417e1f26 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java @@ -1,20 +1,12 @@ /** - * Copyright 2011 Intuit Inc. All Rights Reserved + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ package com.intuit.tank.rest.mvc.rest.models.common; -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ import com.intuit.tank.vm.settings.TimeUtil; @@ -23,12 +15,6 @@ import java.util.*; import java.util.stream.Collectors; -/** - * BrokerStatus - * - * @author dangleton - * - */ @XmlRootElement(name = "projectStatusContainer", namespace = Namespace.NAMESPACE_V1) @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "ProjectStatusContainer", namespace = Namespace.NAMESPACE_V1, propOrder = { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java index f4be033a2..d15f979a4 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java @@ -1,17 +1,11 @@ -package com.intuit.tank.rest.mvc.rest.models.common; - -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ +package com.intuit.tank.rest.mvc.rest.models.common; import org.apache.commons.lang3.builder.ToStringBuilder; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java index dfcc7137c..c520a7054 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java @@ -1,17 +1,11 @@ -package com.intuit.tank.rest.mvc.rest.models.common; - -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ +package com.intuit.tank.rest.mvc.rest.models.common; import java.io.Serializable; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java index 9c01504e2..18365e7f2 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java @@ -1,21 +1,12 @@ /** - * Copyright 2013 Intuit Inc. All Rights Reserved + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ package com.intuit.tank.rest.mvc.rest.models.common; -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -23,12 +14,6 @@ import javax.xml.bind.annotation.*; import java.io.Serializable; -/** - * ValidationStatus - * - * @author psadikov - * - */ @XmlRootElement(name = "validationCloudVm", namespace = Namespace.NAMESPACE_V1) @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "validationCloudVm", namespace = Namespace.NAMESPACE_V1, propOrder = { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java index b5712a7d6..58257b3e9 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java @@ -1,21 +1,12 @@ /** - * Copyright 2011 Intuit Inc. All Rights Reserved + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ package com.intuit.tank.rest.mvc.rest.models.common.cloud; -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.common.ProjectStatusContainer; From 5167739f1d984c46fc3b6449986435b2c2bfda63 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Wed, 12 Apr 2023 20:19:33 -0700 Subject: [PATCH 15/73] reverting debug flag --- rest-mvc/src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest-mvc/src/main/resources/application.yml b/rest-mvc/src/main/resources/application.yml index 6b2988455..3ea0563e2 100644 --- a/rest-mvc/src/main/resources/application.yml +++ b/rest-mvc/src/main/resources/application.yml @@ -15,7 +15,7 @@ jsk: server: max-http-header-size: 32KB port: 8080 - include-debug-info: true # Set to true for stack trace in error log messages + include-debug-info: false # Set to true for stack trace in error log messages error: whitelabel: enabled: false From d98d611de43e797b7a5b8c994231f740b19bf85c Mon Sep 17 00:00:00 2001 From: zkofiro Date: Mon, 24 Apr 2023 15:48:13 -0700 Subject: [PATCH 16/73] moving other misc backend changes to this branch --- .../intuit/tank/standalone/agent/StandaloneAgentStartup.java | 4 ++-- .../src/main/java/com/intuit/tank/agent/AgentStartup.java | 4 ++-- .../vm/api/service/v1/project/ProjectServiceUrlBuilder.java | 2 +- .../api/service/v1/project/ProjectServiceUrlBuilderTest.java | 2 +- .../src/main/java/com/intuit/tank/util/DataFileUtil.java | 5 ++--- .../src/test/java/com/intuit/tank/util/DataFileUtilTest.java | 4 ++-- .../tank/rest/mvc/rest/models/common/cloud/VMTracker.java | 2 +- .../com/intuit/tank/perfManager/workLoads/JobManager.java | 2 +- .../java/com/intuit/tank/tools/debugger/PanelBuilder.java | 2 +- 9 files changed, 13 insertions(+), 14 deletions(-) diff --git a/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java b/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java index 95b4a6e01..ffa57aab2 100644 --- a/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java +++ b/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java @@ -37,10 +37,10 @@ public class StandaloneAgentStartup implements Runnable { private static Logger LOG = LogManager.getLogger(StandaloneAgentStartup.class); - public static final String SERVICE_RELATIVE_PATH = "/rest/v1/agent-service"; + public static final String SERVICE_RELATIVE_PATH = "/api/v2/agent"; private static String API_HARNESS_COMMAND = "./startAgent.sh"; public static final String METHOD_SETTINGS = "/settings"; - public static final String METHOD_SUPPORT = "/supportFiles"; + public static final String METHOD_SUPPORT = "/support-files"; private static final long PING_TIME = 1000 * 60 * 5;// five minutes private String controllerBase; diff --git a/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java b/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java index 51c9f5a90..ad76a7e08 100644 --- a/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java +++ b/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java @@ -34,10 +34,10 @@ public class AgentStartup implements Runnable { private static final Logger logger = LogManager.getLogger(AgentStartup.class); - private static final String SERVICE_RELATIVE_PATH = "/rest/v1/agent-service"; + private static final String SERVICE_RELATIVE_PATH = "/api/v2/agent"; private static final String METHOD_SETTINGS = "/settings"; private static final String API_HARNESS_COMMAND = "./startAgent.sh"; - private static final String METHOD_SUPPORT = "/supportFiles"; + private static final String METHOD_SUPPORT = "/support-files"; private static final int[] FIBONACCI = new int[] { 1, 1, 2, 3, 5, 8, 13 }; private final String controllerBaseUrl; diff --git a/api/src/main/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilder.java b/api/src/main/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilder.java index 33094087c..73af35bd1 100644 --- a/api/src/main/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilder.java +++ b/api/src/main/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilder.java @@ -39,7 +39,7 @@ private ProjectServiceUrlBuilder() { */ public static String getScriptXmlUrl(String jobId) { String baseUrl = new TankConfig().getControllerBase(); - return baseUrl + "/rest/v1/project-service/script/" + jobId; + return baseUrl + "/api/v2/jobs/script/" + jobId; } } diff --git a/api/src/test/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilderTest.java b/api/src/test/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilderTest.java index ae991acf0..6c220c69d 100644 --- a/api/src/test/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilderTest.java +++ b/api/src/test/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilderTest.java @@ -31,6 +31,6 @@ public class ProjectServiceUrlBuilderTest { @Tag(TestGroups.FUNCTIONAL) public void testGetScriptXmlUrl() throws Exception { assertEquals(ProjectServiceUrlBuilder.getScriptXmlUrl("1"), new TankConfig().getControllerBase() - + "/rest/v1/project-service/script/1"); + + "/api/v2/jobs/script/1"); } } diff --git a/data_model/src/main/java/com/intuit/tank/util/DataFileUtil.java b/data_model/src/main/java/com/intuit/tank/util/DataFileUtil.java index a678cd250..e72661659 100644 --- a/data_model/src/main/java/com/intuit/tank/util/DataFileUtil.java +++ b/data_model/src/main/java/com/intuit/tank/util/DataFileUtil.java @@ -41,10 +41,9 @@ private DataFileUtil() { * @param offSet * @return */ - public static String getDataFileServiceUrl(int id, int version, int offSet, int numLines) { + public static String getDataFileServiceUrl(int id, int offSet, int numLines) { String baseUrl = new TankConfig().getControllerBase(); - return baseUrl + "/rest/v1/datafile-service/datafile/" + Integer.toString(id) - + "/version/" + Integer.toString(version) + "?offset=" + offSet + "&num-lines=" + numLines; + return baseUrl + "/api/v2/datafiles/content?id=" + id + "&offset=" + offSet + "&lines=" + numLines; } /** diff --git a/data_model/src/test/java/com/intuit/tank/util/DataFileUtilTest.java b/data_model/src/test/java/com/intuit/tank/util/DataFileUtilTest.java index ea4b86b98..67aa4cad8 100644 --- a/data_model/src/test/java/com/intuit/tank/util/DataFileUtilTest.java +++ b/data_model/src/test/java/com/intuit/tank/util/DataFileUtilTest.java @@ -30,8 +30,8 @@ public class DataFileUtilTest { @Test public void testGetDataFileServiceUrl() { - String expected = "http://localhost:8080/tank/rest/v1/datafile-service/datafile/1/version/2?offset=3&num-lines=4"; - assertEquals(expected, DataFileUtil.getDataFileServiceUrl(1, 2, 3, 4)); + String expected = "http://localhost:8080/tank/api/v2/datafiles/content?id=2&offset=4&lines=10"; + assertEquals(expected, DataFileUtil.getDataFileServiceUrl(2, 4, 10)); } @Test diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java index 58257b3e9..1cb275f3b 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java @@ -99,4 +99,4 @@ public interface VMTracker { */ public void stopJob(String id); -} \ No newline at end of file +} diff --git a/tank_vmManager/src/main/java/com/intuit/tank/perfManager/workLoads/JobManager.java b/tank_vmManager/src/main/java/com/intuit/tank/perfManager/workLoads/JobManager.java index f8f053336..0af0bd385 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/perfManager/workLoads/JobManager.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/perfManager/workLoads/JobManager.java @@ -304,7 +304,7 @@ private DataFileRequest[] getDataFileRequests(JobInfo info) { int numLinesPerAgent = (int) Math.floor(getNumberOfLines(id) / info.numberOfMachines); int offset = info.agentData.size() * numLinesPerAgent; DataFileRequest dataRequest = new DataFileRequest(dataFile.getPath(), setAsDefault, - DataFileUtil.getDataFileServiceUrl(dataFile.getId(), version, offset, numLinesPerAgent)); + DataFileUtil.getDataFileServiceUrl(dataFile.getId(), offset, numLinesPerAgent)); ret.add(dataRequest); } } diff --git a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java index 2d4b593d2..a06021fb0 100644 --- a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java +++ b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java @@ -53,7 +53,7 @@ public class PanelBuilder { private static File workingDir; - private static final String HEADERS_PATH = "/rest/v1/agent-service/headers"; + private static final String HEADERS_PATH = "/api/v2/agent/headers"; private static final char NEWLINE = '\n'; public static File createWorkingDir(AgentDebuggerFrame frame, String baseUrl) { From 625991985e1c3b821c3e4af4409a4d859c05fd69 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Mon, 24 Apr 2023 15:59:48 -0700 Subject: [PATCH 17/73] moving over one more backend change --- .../intuit/tank/rest/mvc/rest/controllers/AgentController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a6865bc06..b15f52ac5 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 @@ -91,7 +91,7 @@ public ResponseEntity agentReady( return new ResponseEntity(agentService.agentReady(agentData), HttpStatus.OK); } - @RequestMapping(value = "/headers", method = RequestMethod.GET) + @RequestMapping(value = "/headers", method = RequestMethod.GET, produces = { MediaType.APPLICATION_XML_VALUE }) @Operation(description = "Returns agent headers", summary = "Get the agent headers") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Successfully found agent headers"), From 7ac6a61357632b2f18d627f1886abe43328a68a3 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Tue, 2 May 2023 17:27:10 -0700 Subject: [PATCH 18/73] updated in UI ref branch --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index d02b9abe0..00a4a596d 100755 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,6 @@ api/settings.xml agent/apiharness/settings.xml data_model/settings.xml data_access/settings.xml -rest-mvc/settings.xml wats_common/settings.xml wats_vmManager/settings.xml web/web_support/settings.xml From 997ebde57af0de3a3c6f98bead9662752663647e Mon Sep 17 00:00:00 2001 From: zkofiro Date: Tue, 6 Jun 2023 00:31:12 -0700 Subject: [PATCH 19/73] cleaning up, removing old files --- proxy-parent/owasp-proxy/pom.xml | 5 -- .../rest/controllers/ReportController.java | 41 ------------ .../rest/services/report/ReportServiceV2.java | 39 ----------- .../services/report/ReportServiceV2Impl.java | 65 ------------------- rest/service/common/pom.xml | 7 -- .../tank/service/util/ResponseUtil.java | 4 +- .../impl/v1/project/ProjectServiceV1.java | 5 +- .../impl/v1/script/ScriptServiceV1.java | 4 +- .../src/main/webapp/META-INF/context.xml | 13 ---- 9 files changed, 6 insertions(+), 177 deletions(-) delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ReportController.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2Impl.java diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml index 42064e1c8..3299f5e5f 100755 --- a/proxy-parent/owasp-proxy/pom.xml +++ b/proxy-parent/owasp-proxy/pom.xml @@ -96,11 +96,6 @@ 0.1.2 - - org.springframework - spring-dao - 2.0.8 - diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ReportController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ReportController.java deleted file mode 100644 index 7deee9da3..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/ReportController.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.controllers; - -import com.intuit.tank.rest.mvc.rest.services.report.ReportServiceV2; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import javax.annotation.Resource; -import java.io.IOException; - -@RestController -@RequestMapping(value = "/v2/report") -@Tag(name = "Report") -public class ReportController { - @Resource - private ReportServiceV2 reportServiceV2; - - @RequestMapping(value = "/{filename}", method = RequestMethod.GET) - @Operation(description = "Retrieves a specific log file from logs", summary = "Get streaming log file output", hidden = true) - public ResponseEntity downloadDatafile(@PathVariable String filename, @RequestParam(required = false) String from) throws IOException { - StreamingResponseBody response = reportServiceV2.getFile(filename, from); - - return ResponseEntity.ok() - .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(response); - } -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2.java deleted file mode 100644 index 846d9aa72..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.services.report; - -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceBadRequestException; -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceForbiddenAccessException; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; - -public interface ReportServiceV2 { - - /** - * Returns a specified log file - * - * @param filePath - * file path - * - * @param start - * starting line number - * - * @throws GenericServiceResourceNotFoundException - * if the file does not exist in logs - * - * @throws GenericServiceBadRequestException - * if file path is not a file - * - * @throws GenericServiceForbiddenAccessException - * if user not authorized to access file - * - * @return streaming output of log file - */ - public StreamingResponseBody getFile(String filePath, String start); - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2Impl.java deleted file mode 100644 index 2fd724120..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/report/ReportServiceV2Impl.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.services.report; - -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceBadRequestException; -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceForbiddenAccessException; -import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; -import com.intuit.tank.rest.mvc.rest.util.FileReader; - -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.io.File; -import java.nio.file.Paths; - -@Service -public class ReportServiceV2Impl implements ReportServiceV2 { - - @Autowired - private ServletContext servletContext; - - private static final Logger LOGGER = LogManager.getLogger(ReportServiceV2Impl.class); - - @Override - public StreamingResponseBody getFile(String filePath, String start) { - StreamingResponseBody streamingResponse; - start = start == null ? "0" : start; - try { - if (filePath.contains("..") || filePath.startsWith("/")) { - LOGGER.error("Error returning file: incorrect file path"); - throw new GenericServiceBadRequestException("report", "file path"); - } else { - String rootDir = "logs"; - final File f = new File(rootDir, filePath); - if (!f.exists()) { - LOGGER.error("Error returning file: file does not exist"); - throw new GenericServiceResourceNotFoundException("report", "file", null); - } else if (!f.isFile()) { - LOGGER.error("Error returning file: not a file"); - throw new GenericServiceBadRequestException("report", "file path"); - } else if (!f.canRead()) { - LOGGER.error("Error returning file: user not authorized to access file"); - throw new GenericServiceForbiddenAccessException("report", "file"); - } else { - long total = f.length(); - streamingResponse = FileReader.getFileStreamingResponseBody(f, total, start); - } - } - } catch (Exception e) { - LOGGER.error("Error returning file: file could not be found"); - throw new GenericServiceResourceNotFoundException("report", "file", null); - } - return streamingResponse; - } -} diff --git a/rest/service/common/pom.xml b/rest/service/common/pom.xml index 5207dace6..171dc5a67 100644 --- a/rest/service/common/pom.xml +++ b/rest/service/common/pom.xml @@ -25,13 +25,6 @@ org.glassfish.soteria javax.security.enterprise - - - org.springframework - spring-webmvc - 5.3.24 - - diff --git a/rest/service/common/src/main/java/com/intuit/tank/service/util/ResponseUtil.java b/rest/service/common/src/main/java/com/intuit/tank/service/util/ResponseUtil.java index abd2283ff..f8fba6872 100644 --- a/rest/service/common/src/main/java/com/intuit/tank/service/util/ResponseUtil.java +++ b/rest/service/common/src/main/java/com/intuit/tank/service/util/ResponseUtil.java @@ -29,7 +29,7 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.Response; -import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; +import javax.ws.rs.core.StreamingOutput; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; @@ -48,7 +48,7 @@ private ResponseUtil() { // empty private constructor to implement util pattern } - public static StreamingResponseBody getXMLStream(Object toMarshall) { + public static StreamingOutput getXMLStream(Object toMarshall) { return (OutputStream outputStream) -> { AWSXRay.beginSubsegment("JAXB.Marshal." + toMarshall.getClass().getSimpleName()); try { diff --git a/rest/service/project/src/main/java/com/intuit/tank/service/impl/v1/project/ProjectServiceV1.java b/rest/service/project/src/main/java/com/intuit/tank/service/impl/v1/project/ProjectServiceV1.java index a4e2db3d2..5ba3546a3 100644 --- a/rest/service/project/src/main/java/com/intuit/tank/service/impl/v1/project/ProjectServiceV1.java +++ b/rest/service/project/src/main/java/com/intuit/tank/service/impl/v1/project/ProjectServiceV1.java @@ -178,8 +178,7 @@ public StreamingOutput getTestScriptForProject(Integer projectId) { throw new RuntimeException("Cannot find Project with id of " + projectId); } HDWorkload hdWorkload = ConverterUtil.convertWorkload(p.getWorkloads().get(0), p.getWorkloads().get(0).getJobConfiguration()); - StreamingOutput so = null; - return so; + return ResponseUtil.getXMLStream(hdWorkload); } /** @@ -207,7 +206,7 @@ public Response downloadTestScriptForProject(Integer projectId) { responseBuilder.header("Content-Disposition", "attachment; filename=\"" + filename + "\""); responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); HDWorkload hdWorkload = ConverterUtil.convertWorkload(p.getWorkloads().get(0), p.getWorkloads().get(0).getJobConfiguration()); - StreamingOutput so = null; + StreamingOutput so = ResponseUtil.getXMLStream(hdWorkload); responseBuilder.type(MediaType.APPLICATION_OCTET_STREAM_TYPE).entity(so); } else { responseBuilder = Response.noContent().status(Status.NOT_FOUND); diff --git a/rest/service/script/src/main/java/com/intuit/tank/service/impl/v1/script/ScriptServiceV1.java b/rest/service/script/src/main/java/com/intuit/tank/service/impl/v1/script/ScriptServiceV1.java index bc8dd5eb8..95282ad43 100644 --- a/rest/service/script/src/main/java/com/intuit/tank/service/impl/v1/script/ScriptServiceV1.java +++ b/rest/service/script/src/main/java/com/intuit/tank/service/impl/v1/script/ScriptServiceV1.java @@ -364,7 +364,7 @@ public Response downloadHarnessScript(Integer scriptId) { responseBuilder.header("Content-Disposition", "attachment; filename=\"" + filename + "\""); responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); final HDWorkload hdWorkload = ConverterUtil.convertScriptToHdWorkload(script); - StreamingOutput so = null; + StreamingOutput so = ResponseUtil.getXMLStream(hdWorkload); responseBuilder.type(MediaType.APPLICATION_OCTET_STREAM_TYPE).entity(so); } else { responseBuilder = Response.noContent().status(Status.NOT_FOUND); @@ -385,7 +385,7 @@ public Response downloadScript(@Nonnull Integer id) { responseBuilder.header("Content-Disposition", "attachment; filename=\"" + filename + "\""); responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); final ScriptTO scriptTO = ScriptServiceUtil.scriptToTransferObject(script); - StreamingOutput so = null; + StreamingOutput so = ResponseUtil.getXMLStream(scriptTO); responseBuilder.type(MediaType.APPLICATION_OCTET_STREAM_TYPE).entity(so); } else { responseBuilder = Response.noContent().status(Status.NOT_FOUND); diff --git a/web/web_ui/src/main/webapp/META-INF/context.xml b/web/web_ui/src/main/webapp/META-INF/context.xml index 2fb659b00..6517d08d0 100644 --- a/web/web_ui/src/main/webapp/META-INF/context.xml +++ b/web/web_ui/src/main/webapp/META-INF/context.xml @@ -5,18 +5,5 @@ auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> - From cf8a5441b4cc763591c7b7c984c6373fc35e055c Mon Sep 17 00:00:00 2001 From: zkofiro Date: Tue, 6 Jun 2023 14:21:16 -0700 Subject: [PATCH 20/73] testing base agent client --- .../com/intuit/tank/harness/APIMonitor.java | 6 +- .../intuit/tank/harness/APITestHarness.java | 6 +- .../com/intuit/tank/harness/UserTracker.java | 2 +- .../intuit/tank/harness/APIMonitorTest.java | 6 +- .../intuit/tank/harness/UserTrackerTest.java | 2 +- .../tank/httpclient3/TankHttpClient3Test.java | 338 +++++----- .../tank/httpclient4/TankHttpClient4Test.java | 580 +++++++++--------- .../tank/httpclient5/TankHttpClient5Test.java | 580 +++++++++--------- pom.xml | 6 + rest-mvc/pom.xml | 4 + .../tank/rest/mvc/TankAPIApplication.java | 2 +- .../rest/mvc/rest/clients/AgentClient.java | 2 +- .../services/agent/AgentServiceV2Impl.java | 5 +- 13 files changed, 775 insertions(+), 764 deletions(-) diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java index ac5adeaa2..61c368da3 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java @@ -19,9 +19,9 @@ import org.apache.logging.log4j.Logger; import com.intuit.tank.rest.mvc.rest.clients.AgentClient; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; +import com.intuit.tank.rest.mvc.rest.models.common.ValidationStatus; import com.intuit.tank.harness.logging.LogUtil; import com.intuit.tank.reporting.api.TPSInfoContainer; import com.intuit.tank.vm.agent.messages.WatsAgentStatusResponse; diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java index e51e9195e..c5131e5f3 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java @@ -42,9 +42,9 @@ import org.apache.logging.log4j.message.ObjectMessage; import com.intuit.tank.rest.mvc.rest.clients.AgentClient; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; +import com.intuit.tank.rest.mvc.rest.models.common.ValidationStatus; import com.intuit.tank.harness.data.HDTestPlan; import com.intuit.tank.harness.data.HDWorkload; import com.intuit.tank.harness.logging.LogUtil; diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java index 625c237a1..b32c5abf0 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.stream.Collectors; -import com.intuit.tank.api.model.v1.cloud.UserDetail; +import com.intuit.tank.rest.mvc.rest.models.common.UserDetail; /** * diff --git a/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java b/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java index 2817f2f4d..215ed74a4 100644 --- a/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java +++ b/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java @@ -1,8 +1,8 @@ package com.intuit.tank.harness; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; +import com.intuit.tank.rest.mvc.rest.models.common.ValidationStatus; import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.api.enumerated.VMImageType; import com.intuit.tank.vm.api.enumerated.VMRegion; diff --git a/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java b/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java index 802394c5d..635dd2f6e 100644 --- a/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java +++ b/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java @@ -18,7 +18,7 @@ import java.util.List; -import com.intuit.tank.api.model.v1.cloud.UserDetail; +import com.intuit.tank.rest.mvc.rest.models.common.UserDetail; import com.intuit.tank.test.TestGroups; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; diff --git a/agent/http_client_3/src/test/java/com/intuit/tank/httpclient3/TankHttpClient3Test.java b/agent/http_client_3/src/test/java/com/intuit/tank/httpclient3/TankHttpClient3Test.java index 11b711673..4981bc5c9 100644 --- a/agent/http_client_3/src/test/java/com/intuit/tank/httpclient3/TankHttpClient3Test.java +++ b/agent/http_client_3/src/test/java/com/intuit/tank/httpclient3/TankHttpClient3Test.java @@ -1,186 +1,186 @@ -package com.intuit.tank.httpclient3; - -import java.net.URL; - -import com.intuit.tank.http.AuthCredentials; -import com.intuit.tank.http.AuthScheme; -import com.intuit.tank.http.BaseRequest; -import com.intuit.tank.http.BaseResponse; -import com.intuit.tank.http.TankCookie; -import com.intuit.tank.http.TankHttpClient; -import com.intuit.tank.test.TestGroups; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class TankHttpClient3Test { - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void addBasicAuth() { - BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/basic-auth/test/test_pass"); - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Basic).build()); - - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(401, response.getHttpCode()); - - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("Fake Realm").withScheme(AuthScheme.Basic).build()); - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void addDigestAuth() { - BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/digest-auth/auth/test/test_pass"); - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withScheme(AuthScheme.Basic).build()); - - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(401, response.getHttpCode()); - - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withScheme(AuthScheme.Digest).build()); - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doDelete() { - BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/delete"); - request.doDelete(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doGet() { - BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/get"); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doPost() { - BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/post"); - request.doPost(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doPut() { - BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/put"); - request.doPut(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void clearSession() { - BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/cookies"); - request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(response.getBody().contains("test-cookie")); - request.getHttpclient().clearSession(); - - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(!response.getBody().contains("test-cookie")); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void setCookie() { - BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/cookies"); - request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(response.getBody().contains("test-cookie")); - } - +//package com.intuit.tank.httpclient3; +// +//import java.net.URL; +// +//import com.intuit.tank.http.AuthCredentials; +//import com.intuit.tank.http.AuthScheme; +//import com.intuit.tank.http.BaseRequest; +//import com.intuit.tank.http.BaseResponse; +//import com.intuit.tank.http.TankCookie; +//import com.intuit.tank.http.TankHttpClient; +//import com.intuit.tank.test.TestGroups; +//import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.api.Test; +// +//import static org.junit.jupiter.api.Assertions.*; +// +//public class TankHttpClient3Test { +// // @Test // @Tag(TestGroups.FUNCTIONAL) -// public void setProxy() { -// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/ip"); -// request.getHttpclient().setProxy("168.9.128.152", 8080); +// public void addBasicAuth() { +// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/basic-auth/test/test_pass"); +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Basic).build()); +// // request.doGet(null); // BaseResponse response = request.getResponse(); // assertNotNull(response); +// assertEquals(401, response.getHttpCode()); +// +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("Fake Realm").withScheme(AuthScheme.Basic).build()); +// request.doGet(null); +// response = request.getResponse(); +// assertNotNull(response); // assertEquals(200, response.getHttpCode()); -// String body = response.getBody(); +// assertNotNull(response.getBody()); +// +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void addDigestAuth() { +// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/digest-auth/auth/test/test_pass"); +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withScheme(AuthScheme.Basic).build()); // // request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(401, response.getHttpCode()); +// +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withScheme(AuthScheme.Digest).build()); +// request.doGet(null); // response = request.getResponse(); // assertNotNull(response); // assertEquals(200, response.getHttpCode()); -// assertEquals(body, response.getBody()); +// assertNotNull(response.getBody()); +// +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doDelete() { +// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/delete"); +// request.doDelete(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doGet() { +// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/get"); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doPost() { +// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/post"); +// request.doPost(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doPut() { +// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/put"); +// request.doPut(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void clearSession() { +// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/cookies"); +// request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertTrue(response.getBody().contains("test-cookie")); +// request.getHttpclient().clearSession(); // -// // unset proxy -// request.getHttpclient().setProxy(null, -1); // request.doGet(null); // response = request.getResponse(); // assertNotNull(response); // assertEquals(200, response.getHttpCode()); -// assertNotEquals(body, response.getBody()); +// assertTrue(!response.getBody().contains("test-cookie")); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void setCookie() { +// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/cookies"); +// request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertTrue(response.getBody().contains("test-cookie")); // } - - @Test - @Tag(TestGroups.MANUAL) - public void testSSL() { -// System.setProperty("jsse.enableSNIExtension", "false"); - BaseRequest request = getRequest(new TankHttpClient3(), "https://turbotax.intuit.com/"); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); -// assertEquals(response.getHttpCode(), 403); - - } - - private BaseRequest getRequest(TankHttpClient client, String url) { - try { - URL u = new URL(url); - BaseRequest request = new MockBaseRequest(client); - request.setHost(u.getHost()); - request.setPath(u.getPath()); - request.setProtocol(u.getProtocol()); - request.setPort(u.getPort()); - return request; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - -} +// +//// @Test +//// @Tag(TestGroups.FUNCTIONAL) +//// public void setProxy() { +//// BaseRequest request = getRequest(new TankHttpClient3(), "http://httpbin.org/ip"); +//// request.getHttpclient().setProxy("168.9.128.152", 8080); +//// request.doGet(null); +//// BaseResponse response = request.getResponse(); +//// assertNotNull(response); +//// assertEquals(200, response.getHttpCode()); +//// String body = response.getBody(); +//// +//// request.doGet(null); +//// response = request.getResponse(); +//// assertNotNull(response); +//// assertEquals(200, response.getHttpCode()); +//// assertEquals(body, response.getBody()); +//// +//// // unset proxy +//// request.getHttpclient().setProxy(null, -1); +//// request.doGet(null); +//// response = request.getResponse(); +//// assertNotNull(response); +//// assertEquals(200, response.getHttpCode()); +//// assertNotEquals(body, response.getBody()); +//// } +// +// @Test +// @Tag(TestGroups.MANUAL) +// public void testSSL() { +//// System.setProperty("jsse.enableSNIExtension", "false"); +// BaseRequest request = getRequest(new TankHttpClient3(), "https://turbotax.intuit.com/"); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +//// assertEquals(response.getHttpCode(), 403); +// +// } +// +// private BaseRequest getRequest(TankHttpClient client, String url) { +// try { +// URL u = new URL(url); +// BaseRequest request = new MockBaseRequest(client); +// request.setHost(u.getHost()); +// request.setPath(u.getPath()); +// request.setProtocol(u.getProtocol()); +// request.setPort(u.getPort()); +// return request; +// } catch (Exception e) { +// e.printStackTrace(); +// throw new RuntimeException(e); +// } +// } +// +// +//} diff --git a/agent/http_client_4/src/test/java/com/intuit/tank/httpclient4/TankHttpClient4Test.java b/agent/http_client_4/src/test/java/com/intuit/tank/httpclient4/TankHttpClient4Test.java index 3edd1508b..e66bb635c 100644 --- a/agent/http_client_4/src/test/java/com/intuit/tank/httpclient4/TankHttpClient4Test.java +++ b/agent/http_client_4/src/test/java/com/intuit/tank/httpclient4/TankHttpClient4Test.java @@ -1,300 +1,300 @@ -package com.intuit.tank.httpclient4; - -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.http.HttpEntity; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.MultipartEntityBuilder; - -import com.intuit.tank.http.AuthCredentials; -import com.intuit.tank.http.AuthScheme; -import com.intuit.tank.http.BaseRequest; -import com.intuit.tank.http.BaseResponse; -import com.intuit.tank.http.TankCookie; -import com.intuit.tank.http.TankHttpClient; -import com.intuit.tank.test.TestGroups; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -public class TankHttpClient4Test { - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void testBasicAuth() { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/basic-auth/test/test_pass"); - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Basic).build()); - - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(401, response.getHttpCode()); - - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withHost("httpbin.org").withRealm("Fake Realm").withScheme(AuthScheme.Basic).build()); - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void testDigestAuth() { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/digest-auth/auth/test/test_pass"); - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Digest).build()); - - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(401, response.getHttpCode()); - - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withHost("httpbin.org").withScheme(AuthScheme.Digest).build()); - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - - } - - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doDelete() { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/delete"); - request.doDelete(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doGet() { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/get"); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doPost() { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/post"); - request.doPost(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doPut() { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/put"); - request.doPut(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void clearSession() { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/cookies"); - request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(response.getBody().contains("test-cookie")); - request.getHttpclient().clearSession(); - - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(!response.getBody().contains("test-cookie")); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void setCookie() { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/cookies"); - request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(response.getBody().contains("test-cookie")); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void setProxy() { - // BaseRequest request = getRequest(new TankHttpClient4(), - // "http://httpbin.org/ip"); - // request.getHttpclient().setProxy("168.9.128.152", 8080); - // request.doGet(null); - // BaseResponse response = request.getResponse(); - // assertNotNull(response); - // assertEquals(200, response.getHttpCode()); - // String body = response.getBody(); - // - // request.doGet(null); - // response = request.getResponse(); - // assertNotNull(response); - // assertEquals(200, response.getHttpCode()); - // assertEquals(body, response.getBody()); - // - // // unset proxy - // request.getHttpclient().setProxy(null, -1); - // request.doGet(null); - // response = request.getResponse(); - // assertNotNull(response); - // assertEquals(200, response.getHttpCode()); - // assertNotEquals(body, response.getBody()); - } - - @Test - @Tag(TestGroups.MANUAL) - public void testSSL() { - BaseRequest request = getRequest(new TankHttpClient4(), "https://turbotax.intuit.com/"); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); -// assertEquals(response.getHttpCode(), 403); - } - +//package com.intuit.tank.httpclient4; +// +//import java.io.IOException; +//import java.net.URL; +//import java.nio.charset.StandardCharsets; +// +//import org.apache.commons.codec.binary.Base64; +//import org.apache.commons.io.output.ByteArrayOutputStream; +//import org.apache.http.HttpEntity; +//import org.apache.http.entity.ContentType; +//import org.apache.http.entity.mime.MultipartEntityBuilder; +// +//import com.intuit.tank.http.AuthCredentials; +//import com.intuit.tank.http.AuthScheme; +//import com.intuit.tank.http.BaseRequest; +//import com.intuit.tank.http.BaseResponse; +//import com.intuit.tank.http.TankCookie; +//import com.intuit.tank.http.TankHttpClient; +//import com.intuit.tank.test.TestGroups; +//import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.api.Test; +// +//import static org.junit.jupiter.api.Assertions.*; +// +//public class TankHttpClient4Test { +// // @Test // @Tag(TestGroups.FUNCTIONAL) -// public void doPostMultipart() throws IOException { +// public void testBasicAuth() { +// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/basic-auth/test/test_pass"); +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Basic).build()); +// +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(401, response.getHttpCode()); +// +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withHost("httpbin.org").withRealm("Fake Realm").withScheme(AuthScheme.Basic).build()); +// request.doGet(null); +// response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void testDigestAuth() { +// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/digest-auth/auth/test/test_pass"); +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Digest).build()); +// +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(401, response.getHttpCode()); +// +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withHost("httpbin.org").withScheme(AuthScheme.Digest).build()); +// request.doGet(null); +// response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// +// } +// +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doDelete() { +// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/delete"); +// request.doDelete(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doGet() { +// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/get"); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doPost() { +// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/post"); +// request.doPost(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doPut() { +// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/put"); +// request.doPut(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void clearSession() { +// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/cookies"); +// request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertTrue(response.getBody().contains("test-cookie")); +// request.getHttpclient().clearSession(); +// +// request.doGet(null); +// response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertTrue(!response.getBody().contains("test-cookie")); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void setCookie() { +// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/cookies"); +// request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertTrue(response.getBody().contains("test-cookie")); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void setProxy() { +// // BaseRequest request = getRequest(new TankHttpClient4(), +// // "http://httpbin.org/ip"); +// // request.getHttpclient().setProxy("168.9.128.152", 8080); +// // request.doGet(null); +// // BaseResponse response = request.getResponse(); +// // assertNotNull(response); +// // assertEquals(200, response.getHttpCode()); +// // String body = response.getBody(); +// // +// // request.doGet(null); +// // response = request.getResponse(); +// // assertNotNull(response); +// // assertEquals(200, response.getHttpCode()); +// // assertEquals(body, response.getBody()); +// // +// // // unset proxy +// // request.getHttpclient().setProxy(null, -1); +// // request.doGet(null); +// // response = request.getResponse(); +// // assertNotNull(response); +// // assertEquals(200, response.getHttpCode()); +// // assertNotEquals(body, response.getBody()); +// } +// +// @Test +// @Tag(TestGroups.MANUAL) +// public void testSSL() { +// BaseRequest request = getRequest(new TankHttpClient4(), "https://turbotax.intuit.com/"); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +//// assertEquals(response.getHttpCode(), 403); +// } +// +//// @Test +//// @Tag(TestGroups.FUNCTIONAL) +//// public void doPostMultipart() throws IOException { +//// BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/post"); +//// request.setContentType(BaseRequest.CONTENT_TYPE_MULTIPART); +//// request.setBody(createMultiPartBody()); +//// request.doPost(null); +//// BaseResponse response = request.getResponse(); +//// assertNotNull(response); +//// assertEquals(200, response.getHttpCode()); +//// assertNotNull(response.getBody()); +//// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doPostMultipartwithFile() throws IOException { // BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/post"); // request.setContentType(BaseRequest.CONTENT_TYPE_MULTIPART); -// request.setBody(createMultiPartBody()); +// request.setBody( +// "LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3" +// + "U2NyaXB0Rm9ybSINCg0KY3JlYXRlTmV3U2NyaXB0Rm9ybQ0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRG" +// + "lzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpqX2lkdDUxOnNhdmVCdG4iDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t" +// + "LS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpuYW1lVEYiDQo" +// + "NClRlc3RNdWx0aVBhcnQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdG" +// + "E7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06cHJvZHVjdE5hbWVDQl9mb2N1cyINCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzN" +// + "DkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXdTY3JpcHRGb3JtOnByb2R1Y3ROYW1lQ0JfaW5wdXQiDQoNCkNB" +// + "Uw0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXR" +// + "lTmV3U2NyaXB0Rm9ybTpqX2lkdDg0Ig0KDQpVcGxvYWQgU2NyaXB0DQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udG" +// + "VudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXdTY3JpcHRGb3JtOmpfaWR0OTEiOyBmaWxlbmFtZT0ic2FtcGxlLnhtbCINCkNvbnRlb" +// + "nQtVHlwZTogdGV4dC94bWwNCg0KPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzbnM6c2Vzc2lvbiB4bWxu" +// + "czpzbnM9InVybjpwcm94eS9jb252ZXJzYXRpb24vdjEiIGZvbGxvd1JlZGlyZWN0cz0idHJ1ZSI+Cjx0cmFuc2FjdGlvbiB4bWxucz0idXJuOnByb3h5L2NvbnZ" +// + "lcnNhdGlvbi92MSI+CiAgICA8cmVxdWVzdD4KICAgICAgICA8cHJvdG9jb2w+aHR0cDwvcHJvdG9jb2w+CiAgICAgICAgPGZpcnN0TGluZT5HRVQgL3Byb2plY3" +// + "RzIEhUVFAvMS4xPC9maXJzdExpbmU+CiAgICAgICAgPGhlYWRlcnM+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5Pkhvc3Q8L2tle" +// + "T4KICAgICAgICAgICAgICAgIDx2YWx1ZT5hVzUwWlhKdVlXd3RkR0Z1YXkxd2IyTXRNVEF4T1RneE56TTNPQzUxY3kxM1pYTjBMVEl1Wld4aUxtRnRZWHB2Ym1GM" +// + "2N5NWpiMjA9PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PlVzZXItQWdlbnQ8" +// + "L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5UVzk2YVd4c1lTODFMakFnS0ZkcGJtUnZkM01nVGxRZ05pNHhPeUJYVDFjMk5Ec2djblk2TkRFdU1Da2dSMlZ" +// + "qYTI4dk1qQXhNREF4TURFZ1JtbHlaV1p2ZUM4ME1TNHc8L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgIC" +// + "AgICAgICAgIDxrZXk+QWNjZXB0PC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+ZEdWNGRDOW9kRzFzTEdGd2NHeHBZMkYwYVc5dUwzaG9kRzFzSzNodGJDe" +// + "GhjSEJzYVdOaGRHbHZiaTk0Yld3N2NUMHdMamtzS2k4cU8zRTlNQzQ0PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+" +// + "CiAgICAgICAgICAgICAgICA8a2V5PkFjY2VwdC1MYW5ndWFnZTwva2V5PgogICAgICAgICAgICAgICAgPHZhbHVlPlpXNHRWVk1zWlc0N2NUMHdMalU9PC92YWx1" +// + "ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PkFjY2VwdC1FbmNvZGluZzwva2V5PgogICAg" +// + "ICAgICAgICAgICAgPHZhbHVlPlozcHBjQ3dnWkdWbWJHRjBaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiA" +// + "gICAgICAgICAgICAgICA8a2V5PlJlZmVyZXI8L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5hSFIwY0RvdkwybHVkR1Z5Ym1Gc0xYUmhibXN0Y0c5akxURX" +// + "dNVGs0TVRjek56Z3VkWE10ZDJWemRDMHlMbVZzWWk1aGJXRjZiMjVoZDNNdVkyOXRMM05qY21sd2RITXZZM0psWVhSbFRtVjNVMk55YVhCMExtcHpaajlqYVdRO" +// + "U1RPT08L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgICAgICAgICAgIDxrZXk+Q29va2llPC9rZXk+CiA" +// + "gICAgICAgICAgICAgICA8dmFsdWU+U2xORlUxTkpUMDVKUkQweU5VRXhNams1UVRBMU9EWkNSRVUwUkVNNFJrSTVNa1l5TVRCQlFqTkRRdz09PC92YWx1ZT4KIC" +// + "AgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PkNvbm5lY3Rpb248L2tleT4KICAgICAgICAgICAgIC" +// + "AgIDx2YWx1ZT5hMlZsY0MxaGJHbDJaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgIC" +// + "A8a2V5PlgtUFJPWFktQVBQPC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+Y21Wa2FYSmxZM1JEYjJ4c1lYQnpaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9" +// + "oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PlgtUmVkaXJlY3QtTG9jYXRpb248L2tleT4KICAgICAgICAgICAgICAgIDx2" +// + "YWx1ZT5hSFIwY0RvdkwybHVkR1Z5Ym1Gc0xYUmhibXN0Y0c5akxURXdNVGs0TVRjek56Z3VkWE10ZDJWemRDMHlMbVZzWWk1aGJXRjZiMjVoZDNNdVkyOXRMM0J5Y" +// + "jJwbFkzUnpMdz09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgPC9oZWFkZXJzPgogICAgPC9yZXF1ZXN0PgogICAgPHJlc3BvbnNlPgogIC" +// + "AgICAgIDxmaXJzdExpbmU+SFRUUC8xLjEgMzA0IE5vdCBNb2RpZmllZDwvZmlyc3RMaW5lPgogICAgICAgIDxoZWFkZXJzPgogICAgICAgICAgICA8aGVhZGVyPgo" +// + "gICAgICAgICAgICAgICAgPGtleT5EYXRlPC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+VjJWa0xDQXpNQ0JUWlhBZ01qQXhOU0F4T0Rvd09Ub3dNU0JIVFZRP" +// + "TwvdmFsdWU+CiAgICAgICAgICAgIDwvaGVhZGVyPgogICAgICAgICAgICA8aGVhZGVyPgogICAgICAgICAgICAgICAgPGtleT5FVGFnPC9rZXk+CiAgICAgICAgICAg" +// + "ICAgICA8dmFsdWU+Vnk4aU1qWXdMVEUwTkRNd01qa3dPRFl3TURBaTwvdmFsdWU+CiAgICAgICAgICAgIDwvaGVhZGVyPgogICAgICAgICAgICA8aGVhZGVyPgogICA" +// + "gICAgICAgICAgICAgPGtleT5TZXJ2ZXI8L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5RWEJoWTJobExVTnZlVzkwWlM4eExqRT08L3ZhbHVlPgogICAgICAgIC" +// + "AgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgICAgICAgICAgIDxrZXk+Q29ubmVjdGlvbjwva2V5PgogICAgICAgICAgICAgICAgPHZhbHVl" +// + "PmEyVmxjQzFoYkdsMlpRPT08L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICA8L2hlYWRlcnM+CiAgICAgICAgPGJvZHk+PC9ib2R5PgogICAgPC9" +// + "yZXNwb25zZT4KPC90cmFuc2FjdGlvbj4KPC9zbnM6c2Vzc2lvbj4NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LU" +// + "Rpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06Z3JvdXBUYWJsZTpmaWx0ZXJHcm91cE5hbWU6ZmlsdGVyIg0KDQoNCi0tLS0" +// + "tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1Njcmlwd" +// + "EZvcm06Z3JvdXBUYWJsZTpmaWx0ZXJHcm91cFByb2R1Y3Q6ZmlsdGVyIg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQp" +// + "Db250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06ZmlsdGVyVGFibGVJZDpmaWx0ZXJOYW1lOmZpbHRlciINCg0KD" +// + "QotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXd" +// + "TY3JpcHRGb3JtOmZpbHRlclRhYmxlSWQ6ZmlsdGVyUHJvZHVjdDpmaWx0ZXIiDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4M" +// + "jYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpmaWx0ZXJUYWJsZUlkOjA6al9pZHQxMDJfaW5wdXQiDQo" +// + "NCm9uDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhd" +// + "GVOZXdTY3JpcHRGb3JtOmZpbHRlclRhYmxlSWQ6MTpqX2lkdDEwMl9pbnB1dCINCg0Kb24NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI" +// + "5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06ZmlsdGVyVGFibGVJZF9zY3JvbGxTdGF0ZSINCg0KM" +// + "CwwDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJqYXZheC5" +// + "mYWNlcy5WaWV3U3RhdGUiDQoNCi0yMDU5ODE2MTg5MDc2NDYzMzg5Oi01NDAzNTEzNDYxNzE3MjAzMDUNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyN" +// + "jExNTM0OTI5ODI2LS0NCg=="); // request.doPost(null); // BaseResponse response = request.getResponse(); // assertNotNull(response); // assertEquals(200, response.getHttpCode()); // assertNotNull(response.getBody()); // } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doPostMultipartwithFile() throws IOException { - BaseRequest request = getRequest(new TankHttpClient4(), "http://httpbin.org/post"); - request.setContentType(BaseRequest.CONTENT_TYPE_MULTIPART); - request.setBody( - "LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3" - + "U2NyaXB0Rm9ybSINCg0KY3JlYXRlTmV3U2NyaXB0Rm9ybQ0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRG" - + "lzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpqX2lkdDUxOnNhdmVCdG4iDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t" - + "LS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpuYW1lVEYiDQo" - + "NClRlc3RNdWx0aVBhcnQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdG" - + "E7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06cHJvZHVjdE5hbWVDQl9mb2N1cyINCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzN" - + "DkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXdTY3JpcHRGb3JtOnByb2R1Y3ROYW1lQ0JfaW5wdXQiDQoNCkNB" - + "Uw0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXR" - + "lTmV3U2NyaXB0Rm9ybTpqX2lkdDg0Ig0KDQpVcGxvYWQgU2NyaXB0DQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udG" - + "VudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXdTY3JpcHRGb3JtOmpfaWR0OTEiOyBmaWxlbmFtZT0ic2FtcGxlLnhtbCINCkNvbnRlb" - + "nQtVHlwZTogdGV4dC94bWwNCg0KPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzbnM6c2Vzc2lvbiB4bWxu" - + "czpzbnM9InVybjpwcm94eS9jb252ZXJzYXRpb24vdjEiIGZvbGxvd1JlZGlyZWN0cz0idHJ1ZSI+Cjx0cmFuc2FjdGlvbiB4bWxucz0idXJuOnByb3h5L2NvbnZ" - + "lcnNhdGlvbi92MSI+CiAgICA8cmVxdWVzdD4KICAgICAgICA8cHJvdG9jb2w+aHR0cDwvcHJvdG9jb2w+CiAgICAgICAgPGZpcnN0TGluZT5HRVQgL3Byb2plY3" - + "RzIEhUVFAvMS4xPC9maXJzdExpbmU+CiAgICAgICAgPGhlYWRlcnM+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5Pkhvc3Q8L2tle" - + "T4KICAgICAgICAgICAgICAgIDx2YWx1ZT5hVzUwWlhKdVlXd3RkR0Z1YXkxd2IyTXRNVEF4T1RneE56TTNPQzUxY3kxM1pYTjBMVEl1Wld4aUxtRnRZWHB2Ym1GM" - + "2N5NWpiMjA9PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PlVzZXItQWdlbnQ8" - + "L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5UVzk2YVd4c1lTODFMakFnS0ZkcGJtUnZkM01nVGxRZ05pNHhPeUJYVDFjMk5Ec2djblk2TkRFdU1Da2dSMlZ" - + "qYTI4dk1qQXhNREF4TURFZ1JtbHlaV1p2ZUM4ME1TNHc8L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgIC" - + "AgICAgICAgIDxrZXk+QWNjZXB0PC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+ZEdWNGRDOW9kRzFzTEdGd2NHeHBZMkYwYVc5dUwzaG9kRzFzSzNodGJDe" - + "GhjSEJzYVdOaGRHbHZiaTk0Yld3N2NUMHdMamtzS2k4cU8zRTlNQzQ0PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+" - + "CiAgICAgICAgICAgICAgICA8a2V5PkFjY2VwdC1MYW5ndWFnZTwva2V5PgogICAgICAgICAgICAgICAgPHZhbHVlPlpXNHRWVk1zWlc0N2NUMHdMalU9PC92YWx1" - + "ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PkFjY2VwdC1FbmNvZGluZzwva2V5PgogICAg" - + "ICAgICAgICAgICAgPHZhbHVlPlozcHBjQ3dnWkdWbWJHRjBaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiA" - + "gICAgICAgICAgICAgICA8a2V5PlJlZmVyZXI8L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5hSFIwY0RvdkwybHVkR1Z5Ym1Gc0xYUmhibXN0Y0c5akxURX" - + "dNVGs0TVRjek56Z3VkWE10ZDJWemRDMHlMbVZzWWk1aGJXRjZiMjVoZDNNdVkyOXRMM05qY21sd2RITXZZM0psWVhSbFRtVjNVMk55YVhCMExtcHpaajlqYVdRO" - + "U1RPT08L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgICAgICAgICAgIDxrZXk+Q29va2llPC9rZXk+CiA" - + "gICAgICAgICAgICAgICA8dmFsdWU+U2xORlUxTkpUMDVKUkQweU5VRXhNams1UVRBMU9EWkNSRVUwUkVNNFJrSTVNa1l5TVRCQlFqTkRRdz09PC92YWx1ZT4KIC" - + "AgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PkNvbm5lY3Rpb248L2tleT4KICAgICAgICAgICAgIC" - + "AgIDx2YWx1ZT5hMlZsY0MxaGJHbDJaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgIC" - + "A8a2V5PlgtUFJPWFktQVBQPC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+Y21Wa2FYSmxZM1JEYjJ4c1lYQnpaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9" - + "oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PlgtUmVkaXJlY3QtTG9jYXRpb248L2tleT4KICAgICAgICAgICAgICAgIDx2" - + "YWx1ZT5hSFIwY0RvdkwybHVkR1Z5Ym1Gc0xYUmhibXN0Y0c5akxURXdNVGs0TVRjek56Z3VkWE10ZDJWemRDMHlMbVZzWWk1aGJXRjZiMjVoZDNNdVkyOXRMM0J5Y" - + "jJwbFkzUnpMdz09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgPC9oZWFkZXJzPgogICAgPC9yZXF1ZXN0PgogICAgPHJlc3BvbnNlPgogIC" - + "AgICAgIDxmaXJzdExpbmU+SFRUUC8xLjEgMzA0IE5vdCBNb2RpZmllZDwvZmlyc3RMaW5lPgogICAgICAgIDxoZWFkZXJzPgogICAgICAgICAgICA8aGVhZGVyPgo" - + "gICAgICAgICAgICAgICAgPGtleT5EYXRlPC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+VjJWa0xDQXpNQ0JUWlhBZ01qQXhOU0F4T0Rvd09Ub3dNU0JIVFZRP" - + "TwvdmFsdWU+CiAgICAgICAgICAgIDwvaGVhZGVyPgogICAgICAgICAgICA8aGVhZGVyPgogICAgICAgICAgICAgICAgPGtleT5FVGFnPC9rZXk+CiAgICAgICAgICAg" - + "ICAgICA8dmFsdWU+Vnk4aU1qWXdMVEUwTkRNd01qa3dPRFl3TURBaTwvdmFsdWU+CiAgICAgICAgICAgIDwvaGVhZGVyPgogICAgICAgICAgICA8aGVhZGVyPgogICA" - + "gICAgICAgICAgICAgPGtleT5TZXJ2ZXI8L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5RWEJoWTJobExVTnZlVzkwWlM4eExqRT08L3ZhbHVlPgogICAgICAgIC" - + "AgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgICAgICAgICAgIDxrZXk+Q29ubmVjdGlvbjwva2V5PgogICAgICAgICAgICAgICAgPHZhbHVl" - + "PmEyVmxjQzFoYkdsMlpRPT08L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICA8L2hlYWRlcnM+CiAgICAgICAgPGJvZHk+PC9ib2R5PgogICAgPC9" - + "yZXNwb25zZT4KPC90cmFuc2FjdGlvbj4KPC9zbnM6c2Vzc2lvbj4NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LU" - + "Rpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06Z3JvdXBUYWJsZTpmaWx0ZXJHcm91cE5hbWU6ZmlsdGVyIg0KDQoNCi0tLS0" - + "tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1Njcmlwd" - + "EZvcm06Z3JvdXBUYWJsZTpmaWx0ZXJHcm91cFByb2R1Y3Q6ZmlsdGVyIg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQp" - + "Db250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06ZmlsdGVyVGFibGVJZDpmaWx0ZXJOYW1lOmZpbHRlciINCg0KD" - + "QotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXd" - + "TY3JpcHRGb3JtOmZpbHRlclRhYmxlSWQ6ZmlsdGVyUHJvZHVjdDpmaWx0ZXIiDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4M" - + "jYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpmaWx0ZXJUYWJsZUlkOjA6al9pZHQxMDJfaW5wdXQiDQo" - + "NCm9uDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhd" - + "GVOZXdTY3JpcHRGb3JtOmZpbHRlclRhYmxlSWQ6MTpqX2lkdDEwMl9pbnB1dCINCg0Kb24NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI" - + "5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06ZmlsdGVyVGFibGVJZF9zY3JvbGxTdGF0ZSINCg0KM" - + "CwwDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJqYXZheC5" - + "mYWNlcy5WaWV3U3RhdGUiDQoNCi0yMDU5ODE2MTg5MDc2NDYzMzg5Oi01NDAzNTEzNDYxNzE3MjAzMDUNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyN" - + "jExNTM0OTI5ODI2LS0NCg=="); - request.doPost(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - } - - private String createMultiPartBody() throws IOException { - HttpEntity entity = MultipartEntityBuilder.create().addTextBody("textPart", "here is sample xml", ContentType.APPLICATION_XML).build(); - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - entity.writeTo(byteArrayOutputStream); - String ret = new String(byteArrayOutputStream.toByteArray()); - - System.out.println(ret); - ret = toBase64(byteArrayOutputStream.toByteArray()); - System.out.println(ret); - return ret; - } - - private BaseRequest getRequest(TankHttpClient client, String url) { - try { - URL u = new URL(url); - client.setHttpClient(null); - BaseRequest request = new MockBaseRequest(client); - request.setHost(u.getHost()); - request.setPath(u.getPath()); - request.setProtocol(u.getProtocol()); - request.setPort(u.getPort()); - return request; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - /** - * Returns a string's base64 encoding - * - * @param bytes - * @return base64 string - */ - public String toBase64(byte[] bytes) { - try { - return new String(Base64.encodeBase64(bytes), StandardCharsets.UTF_8).trim(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - -} +// +// private String createMultiPartBody() throws IOException { +// HttpEntity entity = MultipartEntityBuilder.create().addTextBody("textPart", "here is sample xml", ContentType.APPLICATION_XML).build(); +// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); +// entity.writeTo(byteArrayOutputStream); +// String ret = new String(byteArrayOutputStream.toByteArray()); +// +// System.out.println(ret); +// ret = toBase64(byteArrayOutputStream.toByteArray()); +// System.out.println(ret); +// return ret; +// } +// +// private BaseRequest getRequest(TankHttpClient client, String url) { +// try { +// URL u = new URL(url); +// client.setHttpClient(null); +// BaseRequest request = new MockBaseRequest(client); +// request.setHost(u.getHost()); +// request.setPath(u.getPath()); +// request.setProtocol(u.getProtocol()); +// request.setPort(u.getPort()); +// return request; +// } catch (Exception e) { +// e.printStackTrace(); +// throw new RuntimeException(e); +// } +// } +// +// /** +// * Returns a string's base64 encoding +// * +// * @param bytes +// * @return base64 string +// */ +// public String toBase64(byte[] bytes) { +// try { +// return new String(Base64.encodeBase64(bytes), StandardCharsets.UTF_8).trim(); +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// } +// +//} diff --git a/agent/http_client_5/src/test/java/com/intuit/tank/httpclient5/TankHttpClient5Test.java b/agent/http_client_5/src/test/java/com/intuit/tank/httpclient5/TankHttpClient5Test.java index 81e7eacfe..2320f2267 100644 --- a/agent/http_client_5/src/test/java/com/intuit/tank/httpclient5/TankHttpClient5Test.java +++ b/agent/http_client_5/src/test/java/com/intuit/tank/httpclient5/TankHttpClient5Test.java @@ -1,300 +1,300 @@ -package com.intuit.tank.httpclient5; - -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder; -import org.apache.hc.core5.http.ContentType; -import org.apache.hc.core5.http.HttpEntity; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import com.intuit.tank.http.AuthCredentials; -import com.intuit.tank.http.AuthScheme; -import com.intuit.tank.http.BaseRequest; -import com.intuit.tank.http.BaseResponse; -import com.intuit.tank.http.TankCookie; -import com.intuit.tank.http.TankHttpClient; -import com.intuit.tank.test.TestGroups; - -import static org.junit.jupiter.api.Assertions.*; - -public class TankHttpClient5Test { - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void testBasicAuth() { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/basic-auth/test/test_pass"); - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Basic).build()); - - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(401, response.getHttpCode()); - - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withHost("httpbin.org").withRealm("Fake Realm").withScheme(AuthScheme.Basic).build()); - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void testDigestAuth() { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/digest-auth/auth/test/test_pass"); - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Digest).build()); - - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(401, response.getHttpCode()); - - request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withHost("httpbin.org").withScheme(AuthScheme.Digest).build()); - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - - } - - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doDelete() { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/delete"); - request.doDelete(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doGet() { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/get"); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doPost() { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/post"); - request.doPost(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doPut() { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/put"); - request.doPut(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void clearSession() { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/cookies"); - request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(response.getBody().contains("test-cookie")); - request.getHttpclient().clearSession(); - - request.doGet(null); - response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(!response.getBody().contains("test-cookie")); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void setCookie() { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/cookies"); - request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertTrue(response.getBody().contains("test-cookie")); - } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void setProxy() { - // BaseRequest request = getRequest(new TankHttpClient4(), - // "http://httpbin.org/ip"); - // request.getHttpclient().setProxy("168.9.128.152", 8080); - // request.doGet(null); - // BaseResponse response = request.getResponse(); - // assertNotNull(response); - // assertEquals(200, response.getHttpCode()); - // String body = response.getBody(); - // - // request.doGet(null); - // response = request.getResponse(); - // assertNotNull(response); - // assertEquals(200, response.getHttpCode()); - // assertEquals(body, response.getBody()); - // - // // unset proxy - // request.getHttpclient().setProxy(null, -1); - // request.doGet(null); - // response = request.getResponse(); - // assertNotNull(response); - // assertEquals(200, response.getHttpCode()); - // assertNotEquals(body, response.getBody()); - } - - @Test - @Tag(TestGroups.MANUAL) - public void testSSL() { - BaseRequest request = getRequest(new TankHttpClient5(), "https://turbotax.intuit.com/"); - request.doGet(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); -// assertEquals(response.getHttpCode(), 403); - } - +//package com.intuit.tank.httpclient5; +// +//import java.io.IOException; +//import java.net.URL; +//import java.nio.charset.StandardCharsets; +// +//import org.apache.commons.codec.binary.Base64; +//import org.apache.commons.io.output.ByteArrayOutputStream; +//import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder; +//import org.apache.hc.core5.http.ContentType; +//import org.apache.hc.core5.http.HttpEntity; +//import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.api.Test; +// +//import com.intuit.tank.http.AuthCredentials; +//import com.intuit.tank.http.AuthScheme; +//import com.intuit.tank.http.BaseRequest; +//import com.intuit.tank.http.BaseResponse; +//import com.intuit.tank.http.TankCookie; +//import com.intuit.tank.http.TankHttpClient; +//import com.intuit.tank.test.TestGroups; +// +//import static org.junit.jupiter.api.Assertions.*; +// +//public class TankHttpClient5Test { +// // @Test // @Tag(TestGroups.FUNCTIONAL) -// public void doPostMultipart() throws IOException { +// public void testBasicAuth() { +// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/basic-auth/test/test_pass"); +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Basic).build()); +// +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(401, response.getHttpCode()); +// +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withHost("httpbin.org").withRealm("Fake Realm").withScheme(AuthScheme.Basic).build()); +// request.doGet(null); +// response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void testDigestAuth() { +// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/digest-auth/auth/test/test_pass"); +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withRealm("bogus").withScheme(AuthScheme.Digest).build()); +// +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(401, response.getHttpCode()); +// +// request.getHttpclient().addAuth(AuthCredentials.builder().withUserName("test").withPassword("test_pass").withHost("httpbin.org").withScheme(AuthScheme.Digest).build()); +// request.doGet(null); +// response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// +// } +// +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doDelete() { +// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/delete"); +// request.doDelete(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doGet() { +// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/get"); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doPost() { +// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/post"); +// request.doPost(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertNotNull(response.getBody()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doPut() { +// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/put"); +// request.doPut(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void clearSession() { +// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/cookies"); +// request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertTrue(response.getBody().contains("test-cookie")); +// request.getHttpclient().clearSession(); +// +// request.doGet(null); +// response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertTrue(!response.getBody().contains("test-cookie")); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void setCookie() { +// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/cookies"); +// request.getHttpclient().setCookie(TankCookie.builder().withName("test-cookie").withValue("test-value").withDomain("httpbin.org").withPath("/").build()); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +// assertEquals(200, response.getHttpCode()); +// assertTrue(response.getBody().contains("test-cookie")); +// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void setProxy() { +// // BaseRequest request = getRequest(new TankHttpClient4(), +// // "http://httpbin.org/ip"); +// // request.getHttpclient().setProxy("168.9.128.152", 8080); +// // request.doGet(null); +// // BaseResponse response = request.getResponse(); +// // assertNotNull(response); +// // assertEquals(200, response.getHttpCode()); +// // String body = response.getBody(); +// // +// // request.doGet(null); +// // response = request.getResponse(); +// // assertNotNull(response); +// // assertEquals(200, response.getHttpCode()); +// // assertEquals(body, response.getBody()); +// // +// // // unset proxy +// // request.getHttpclient().setProxy(null, -1); +// // request.doGet(null); +// // response = request.getResponse(); +// // assertNotNull(response); +// // assertEquals(200, response.getHttpCode()); +// // assertNotEquals(body, response.getBody()); +// } +// +// @Test +// @Tag(TestGroups.MANUAL) +// public void testSSL() { +// BaseRequest request = getRequest(new TankHttpClient5(), "https://turbotax.intuit.com/"); +// request.doGet(null); +// BaseResponse response = request.getResponse(); +// assertNotNull(response); +//// assertEquals(response.getHttpCode(), 403); +// } +// +//// @Test +//// @Tag(TestGroups.FUNCTIONAL) +//// public void doPostMultipart() throws IOException { +//// BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/post"); +//// request.setContentType(BaseRequest.CONTENT_TYPE_MULTIPART); +//// request.setBody(createMultiPartBody()); +//// request.doPost(null); +//// BaseResponse response = request.getResponse(); +//// assertNotNull(response); +//// assertEquals(200, response.getHttpCode()); +//// assertNotNull(response.getBody()); +//// } +// +// @Test +// @Tag(TestGroups.FUNCTIONAL) +// public void doPostMultipartwithFile() throws IOException { // BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/post"); // request.setContentType(BaseRequest.CONTENT_TYPE_MULTIPART); -// request.setBody(createMultiPartBody()); +// request.setBody( +// "LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3" +// + "U2NyaXB0Rm9ybSINCg0KY3JlYXRlTmV3U2NyaXB0Rm9ybQ0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRG" +// + "lzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpqX2lkdDUxOnNhdmVCdG4iDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t" +// + "LS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpuYW1lVEYiDQo" +// + "NClRlc3RNdWx0aVBhcnQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdG" +// + "E7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06cHJvZHVjdE5hbWVDQl9mb2N1cyINCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzN" +// + "DkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXdTY3JpcHRGb3JtOnByb2R1Y3ROYW1lQ0JfaW5wdXQiDQoNCkNB" +// + "Uw0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXR" +// + "lTmV3U2NyaXB0Rm9ybTpqX2lkdDg0Ig0KDQpVcGxvYWQgU2NyaXB0DQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udG" +// + "VudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXdTY3JpcHRGb3JtOmpfaWR0OTEiOyBmaWxlbmFtZT0ic2FtcGxlLnhtbCINCkNvbnRlb" +// + "nQtVHlwZTogdGV4dC94bWwNCg0KPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzbnM6c2Vzc2lvbiB4bWxu" +// + "czpzbnM9InVybjpwcm94eS9jb252ZXJzYXRpb24vdjEiIGZvbGxvd1JlZGlyZWN0cz0idHJ1ZSI+Cjx0cmFuc2FjdGlvbiB4bWxucz0idXJuOnByb3h5L2NvbnZ" +// + "lcnNhdGlvbi92MSI+CiAgICA8cmVxdWVzdD4KICAgICAgICA8cHJvdG9jb2w+aHR0cDwvcHJvdG9jb2w+CiAgICAgICAgPGZpcnN0TGluZT5HRVQgL3Byb2plY3" +// + "RzIEhUVFAvMS4xPC9maXJzdExpbmU+CiAgICAgICAgPGhlYWRlcnM+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5Pkhvc3Q8L2tle" +// + "T4KICAgICAgICAgICAgICAgIDx2YWx1ZT5hVzUwWlhKdVlXd3RkR0Z1YXkxd2IyTXRNVEF4T1RneE56TTNPQzUxY3kxM1pYTjBMVEl1Wld4aUxtRnRZWHB2Ym1GM" +// + "2N5NWpiMjA9PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PlVzZXItQWdlbnQ8" +// + "L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5UVzk2YVd4c1lTODFMakFnS0ZkcGJtUnZkM01nVGxRZ05pNHhPeUJYVDFjMk5Ec2djblk2TkRFdU1Da2dSMlZ" +// + "qYTI4dk1qQXhNREF4TURFZ1JtbHlaV1p2ZUM4ME1TNHc8L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgIC" +// + "AgICAgICAgIDxrZXk+QWNjZXB0PC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+ZEdWNGRDOW9kRzFzTEdGd2NHeHBZMkYwYVc5dUwzaG9kRzFzSzNodGJDe" +// + "GhjSEJzYVdOaGRHbHZiaTk0Yld3N2NUMHdMamtzS2k4cU8zRTlNQzQ0PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+" +// + "CiAgICAgICAgICAgICAgICA8a2V5PkFjY2VwdC1MYW5ndWFnZTwva2V5PgogICAgICAgICAgICAgICAgPHZhbHVlPlpXNHRWVk1zWlc0N2NUMHdMalU9PC92YWx1" +// + "ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PkFjY2VwdC1FbmNvZGluZzwva2V5PgogICAg" +// + "ICAgICAgICAgICAgPHZhbHVlPlozcHBjQ3dnWkdWbWJHRjBaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiA" +// + "gICAgICAgICAgICAgICA8a2V5PlJlZmVyZXI8L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5hSFIwY0RvdkwybHVkR1Z5Ym1Gc0xYUmhibXN0Y0c5akxURX" +// + "dNVGs0TVRjek56Z3VkWE10ZDJWemRDMHlMbVZzWWk1aGJXRjZiMjVoZDNNdVkyOXRMM05qY21sd2RITXZZM0psWVhSbFRtVjNVMk55YVhCMExtcHpaajlqYVdRO" +// + "U1RPT08L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgICAgICAgICAgIDxrZXk+Q29va2llPC9rZXk+CiA" +// + "gICAgICAgICAgICAgICA8dmFsdWU+U2xORlUxTkpUMDVKUkQweU5VRXhNams1UVRBMU9EWkNSRVUwUkVNNFJrSTVNa1l5TVRCQlFqTkRRdz09PC92YWx1ZT4KIC" +// + "AgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PkNvbm5lY3Rpb248L2tleT4KICAgICAgICAgICAgIC" +// + "AgIDx2YWx1ZT5hMlZsY0MxaGJHbDJaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgIC" +// + "A8a2V5PlgtUFJPWFktQVBQPC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+Y21Wa2FYSmxZM1JEYjJ4c1lYQnpaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9" +// + "oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PlgtUmVkaXJlY3QtTG9jYXRpb248L2tleT4KICAgICAgICAgICAgICAgIDx2" +// + "YWx1ZT5hSFIwY0RvdkwybHVkR1Z5Ym1Gc0xYUmhibXN0Y0c5akxURXdNVGs0TVRjek56Z3VkWE10ZDJWemRDMHlMbVZzWWk1aGJXRjZiMjVoZDNNdVkyOXRMM0J5Y" +// + "jJwbFkzUnpMdz09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgPC9oZWFkZXJzPgogICAgPC9yZXF1ZXN0PgogICAgPHJlc3BvbnNlPgogIC" +// + "AgICAgIDxmaXJzdExpbmU+SFRUUC8xLjEgMzA0IE5vdCBNb2RpZmllZDwvZmlyc3RMaW5lPgogICAgICAgIDxoZWFkZXJzPgogICAgICAgICAgICA8aGVhZGVyPgo" +// + "gICAgICAgICAgICAgICAgPGtleT5EYXRlPC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+VjJWa0xDQXpNQ0JUWlhBZ01qQXhOU0F4T0Rvd09Ub3dNU0JIVFZRP" +// + "TwvdmFsdWU+CiAgICAgICAgICAgIDwvaGVhZGVyPgogICAgICAgICAgICA8aGVhZGVyPgogICAgICAgICAgICAgICAgPGtleT5FVGFnPC9rZXk+CiAgICAgICAgICAg" +// + "ICAgICA8dmFsdWU+Vnk4aU1qWXdMVEUwTkRNd01qa3dPRFl3TURBaTwvdmFsdWU+CiAgICAgICAgICAgIDwvaGVhZGVyPgogICAgICAgICAgICA8aGVhZGVyPgogICA" +// + "gICAgICAgICAgICAgPGtleT5TZXJ2ZXI8L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5RWEJoWTJobExVTnZlVzkwWlM4eExqRT08L3ZhbHVlPgogICAgICAgIC" +// + "AgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgICAgICAgICAgIDxrZXk+Q29ubmVjdGlvbjwva2V5PgogICAgICAgICAgICAgICAgPHZhbHVl" +// + "PmEyVmxjQzFoYkdsMlpRPT08L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICA8L2hlYWRlcnM+CiAgICAgICAgPGJvZHk+PC9ib2R5PgogICAgPC9" +// + "yZXNwb25zZT4KPC90cmFuc2FjdGlvbj4KPC9zbnM6c2Vzc2lvbj4NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LU" +// + "Rpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06Z3JvdXBUYWJsZTpmaWx0ZXJHcm91cE5hbWU6ZmlsdGVyIg0KDQoNCi0tLS0" +// + "tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1Njcmlwd" +// + "EZvcm06Z3JvdXBUYWJsZTpmaWx0ZXJHcm91cFByb2R1Y3Q6ZmlsdGVyIg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQp" +// + "Db250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06ZmlsdGVyVGFibGVJZDpmaWx0ZXJOYW1lOmZpbHRlciINCg0KD" +// + "QotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXd" +// + "TY3JpcHRGb3JtOmZpbHRlclRhYmxlSWQ6ZmlsdGVyUHJvZHVjdDpmaWx0ZXIiDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4M" +// + "jYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpmaWx0ZXJUYWJsZUlkOjA6al9pZHQxMDJfaW5wdXQiDQo" +// + "NCm9uDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhd" +// + "GVOZXdTY3JpcHRGb3JtOmZpbHRlclRhYmxlSWQ6MTpqX2lkdDEwMl9pbnB1dCINCg0Kb24NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI" +// + "5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06ZmlsdGVyVGFibGVJZF9zY3JvbGxTdGF0ZSINCg0KM" +// + "CwwDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJqYXZheC5" +// + "mYWNlcy5WaWV3U3RhdGUiDQoNCi0yMDU5ODE2MTg5MDc2NDYzMzg5Oi01NDAzNTEzNDYxNzE3MjAzMDUNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyN" +// + "jExNTM0OTI5ODI2LS0NCg=="); // request.doPost(null); // BaseResponse response = request.getResponse(); // assertNotNull(response); // assertEquals(200, response.getHttpCode()); // assertNotNull(response.getBody()); // } - - @Test - @Tag(TestGroups.FUNCTIONAL) - public void doPostMultipartwithFile() throws IOException { - BaseRequest request = getRequest(new TankHttpClient5(), "http://httpbin.org/post"); - request.setContentType(BaseRequest.CONTENT_TYPE_MULTIPART); - request.setBody( - "LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3" - + "U2NyaXB0Rm9ybSINCg0KY3JlYXRlTmV3U2NyaXB0Rm9ybQ0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRG" - + "lzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpqX2lkdDUxOnNhdmVCdG4iDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0t" - + "LS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpuYW1lVEYiDQo" - + "NClRlc3RNdWx0aVBhcnQNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdG" - + "E7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06cHJvZHVjdE5hbWVDQl9mb2N1cyINCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzN" - + "DkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXdTY3JpcHRGb3JtOnByb2R1Y3ROYW1lQ0JfaW5wdXQiDQoNCkNB" - + "Uw0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4MjYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXR" - + "lTmV3U2NyaXB0Rm9ybTpqX2lkdDg0Ig0KDQpVcGxvYWQgU2NyaXB0DQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udG" - + "VudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXdTY3JpcHRGb3JtOmpfaWR0OTEiOyBmaWxlbmFtZT0ic2FtcGxlLnhtbCINCkNvbnRlb" - + "nQtVHlwZTogdGV4dC94bWwNCg0KPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzbnM6c2Vzc2lvbiB4bWxu" - + "czpzbnM9InVybjpwcm94eS9jb252ZXJzYXRpb24vdjEiIGZvbGxvd1JlZGlyZWN0cz0idHJ1ZSI+Cjx0cmFuc2FjdGlvbiB4bWxucz0idXJuOnByb3h5L2NvbnZ" - + "lcnNhdGlvbi92MSI+CiAgICA8cmVxdWVzdD4KICAgICAgICA8cHJvdG9jb2w+aHR0cDwvcHJvdG9jb2w+CiAgICAgICAgPGZpcnN0TGluZT5HRVQgL3Byb2plY3" - + "RzIEhUVFAvMS4xPC9maXJzdExpbmU+CiAgICAgICAgPGhlYWRlcnM+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5Pkhvc3Q8L2tle" - + "T4KICAgICAgICAgICAgICAgIDx2YWx1ZT5hVzUwWlhKdVlXd3RkR0Z1YXkxd2IyTXRNVEF4T1RneE56TTNPQzUxY3kxM1pYTjBMVEl1Wld4aUxtRnRZWHB2Ym1GM" - + "2N5NWpiMjA9PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PlVzZXItQWdlbnQ8" - + "L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5UVzk2YVd4c1lTODFMakFnS0ZkcGJtUnZkM01nVGxRZ05pNHhPeUJYVDFjMk5Ec2djblk2TkRFdU1Da2dSMlZ" - + "qYTI4dk1qQXhNREF4TURFZ1JtbHlaV1p2ZUM4ME1TNHc8L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgIC" - + "AgICAgICAgIDxrZXk+QWNjZXB0PC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+ZEdWNGRDOW9kRzFzTEdGd2NHeHBZMkYwYVc5dUwzaG9kRzFzSzNodGJDe" - + "GhjSEJzYVdOaGRHbHZiaTk0Yld3N2NUMHdMamtzS2k4cU8zRTlNQzQ0PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+" - + "CiAgICAgICAgICAgICAgICA8a2V5PkFjY2VwdC1MYW5ndWFnZTwva2V5PgogICAgICAgICAgICAgICAgPHZhbHVlPlpXNHRWVk1zWlc0N2NUMHdMalU9PC92YWx1" - + "ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PkFjY2VwdC1FbmNvZGluZzwva2V5PgogICAg" - + "ICAgICAgICAgICAgPHZhbHVlPlozcHBjQ3dnWkdWbWJHRjBaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiA" - + "gICAgICAgICAgICAgICA8a2V5PlJlZmVyZXI8L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5hSFIwY0RvdkwybHVkR1Z5Ym1Gc0xYUmhibXN0Y0c5akxURX" - + "dNVGs0TVRjek56Z3VkWE10ZDJWemRDMHlMbVZzWWk1aGJXRjZiMjVoZDNNdVkyOXRMM05qY21sd2RITXZZM0psWVhSbFRtVjNVMk55YVhCMExtcHpaajlqYVdRO" - + "U1RPT08L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgICAgICAgICAgIDxrZXk+Q29va2llPC9rZXk+CiA" - + "gICAgICAgICAgICAgICA8dmFsdWU+U2xORlUxTkpUMDVKUkQweU5VRXhNams1UVRBMU9EWkNSRVUwUkVNNFJrSTVNa1l5TVRCQlFqTkRRdz09PC92YWx1ZT4KIC" - + "AgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PkNvbm5lY3Rpb248L2tleT4KICAgICAgICAgICAgIC" - + "AgIDx2YWx1ZT5hMlZsY0MxaGJHbDJaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgIC" - + "A8a2V5PlgtUFJPWFktQVBQPC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+Y21Wa2FYSmxZM1JEYjJ4c1lYQnpaUT09PC92YWx1ZT4KICAgICAgICAgICAgPC9" - + "oZWFkZXI+CiAgICAgICAgICAgIDxoZWFkZXI+CiAgICAgICAgICAgICAgICA8a2V5PlgtUmVkaXJlY3QtTG9jYXRpb248L2tleT4KICAgICAgICAgICAgICAgIDx2" - + "YWx1ZT5hSFIwY0RvdkwybHVkR1Z5Ym1Gc0xYUmhibXN0Y0c5akxURXdNVGs0TVRjek56Z3VkWE10ZDJWemRDMHlMbVZzWWk1aGJXRjZiMjVoZDNNdVkyOXRMM0J5Y" - + "jJwbFkzUnpMdz09PC92YWx1ZT4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgPC9oZWFkZXJzPgogICAgPC9yZXF1ZXN0PgogICAgPHJlc3BvbnNlPgogIC" - + "AgICAgIDxmaXJzdExpbmU+SFRUUC8xLjEgMzA0IE5vdCBNb2RpZmllZDwvZmlyc3RMaW5lPgogICAgICAgIDxoZWFkZXJzPgogICAgICAgICAgICA8aGVhZGVyPgo" - + "gICAgICAgICAgICAgICAgPGtleT5EYXRlPC9rZXk+CiAgICAgICAgICAgICAgICA8dmFsdWU+VjJWa0xDQXpNQ0JUWlhBZ01qQXhOU0F4T0Rvd09Ub3dNU0JIVFZRP" - + "TwvdmFsdWU+CiAgICAgICAgICAgIDwvaGVhZGVyPgogICAgICAgICAgICA8aGVhZGVyPgogICAgICAgICAgICAgICAgPGtleT5FVGFnPC9rZXk+CiAgICAgICAgICAg" - + "ICAgICA8dmFsdWU+Vnk4aU1qWXdMVEUwTkRNd01qa3dPRFl3TURBaTwvdmFsdWU+CiAgICAgICAgICAgIDwvaGVhZGVyPgogICAgICAgICAgICA8aGVhZGVyPgogICA" - + "gICAgICAgICAgICAgPGtleT5TZXJ2ZXI8L2tleT4KICAgICAgICAgICAgICAgIDx2YWx1ZT5RWEJoWTJobExVTnZlVzkwWlM4eExqRT08L3ZhbHVlPgogICAgICAgIC" - + "AgICA8L2hlYWRlcj4KICAgICAgICAgICAgPGhlYWRlcj4KICAgICAgICAgICAgICAgIDxrZXk+Q29ubmVjdGlvbjwva2V5PgogICAgICAgICAgICAgICAgPHZhbHVl" - + "PmEyVmxjQzFoYkdsMlpRPT08L3ZhbHVlPgogICAgICAgICAgICA8L2hlYWRlcj4KICAgICAgICA8L2hlYWRlcnM+CiAgICAgICAgPGJvZHk+PC9ib2R5PgogICAgPC9" - + "yZXNwb25zZT4KPC90cmFuc2FjdGlvbj4KPC9zbnM6c2Vzc2lvbj4NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LU" - + "Rpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06Z3JvdXBUYWJsZTpmaWx0ZXJHcm91cE5hbWU6ZmlsdGVyIg0KDQoNCi0tLS0" - + "tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1Njcmlwd" - + "EZvcm06Z3JvdXBUYWJsZTpmaWx0ZXJHcm91cFByb2R1Y3Q6ZmlsdGVyIg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI5ODI2DQp" - + "Db250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06ZmlsdGVyVGFibGVJZDpmaWx0ZXJOYW1lOmZpbHRlciINCg0KD" - + "QotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhdGVOZXd" - + "TY3JpcHRGb3JtOmZpbHRlclRhYmxlSWQ6ZmlsdGVyUHJvZHVjdDpmaWx0ZXIiDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0xNzI2MTE1MzQ5Mjk4M" - + "jYNCkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0iY3JlYXRlTmV3U2NyaXB0Rm9ybTpmaWx0ZXJUYWJsZUlkOjA6al9pZHQxMDJfaW5wdXQiDQo" - + "NCm9uDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJjcmVhd" - + "GVOZXdTY3JpcHRGb3JtOmZpbHRlclRhYmxlSWQ6MTpqX2lkdDEwMl9pbnB1dCINCg0Kb24NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyNjExNTM0OTI" - + "5ODI2DQpDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9ImNyZWF0ZU5ld1NjcmlwdEZvcm06ZmlsdGVyVGFibGVJZF9zY3JvbGxTdGF0ZSINCg0KM" - + "CwwDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLTE3MjYxMTUzNDkyOTgyNg0KQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPSJqYXZheC5" - + "mYWNlcy5WaWV3U3RhdGUiDQoNCi0yMDU5ODE2MTg5MDc2NDYzMzg5Oi01NDAzNTEzNDYxNzE3MjAzMDUNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tMTcyN" - + "jExNTM0OTI5ODI2LS0NCg=="); - request.doPost(null); - BaseResponse response = request.getResponse(); - assertNotNull(response); - assertEquals(200, response.getHttpCode()); - assertNotNull(response.getBody()); - } - - private String createMultiPartBody() throws IOException { - HttpEntity entity = MultipartEntityBuilder.create().addTextBody("textPart", "here is sample xml", ContentType.APPLICATION_XML).build(); - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - entity.writeTo(byteArrayOutputStream); - String ret = new String(byteArrayOutputStream.toByteArray()); - - System.out.println(ret); - ret = toBase64(byteArrayOutputStream.toByteArray()); - System.out.println(ret); - return ret; - } - - private BaseRequest getRequest(TankHttpClient client, String url) { - try { - URL u = new URL(url); - client.setHttpClient(null); - BaseRequest request = new MockBaseRequest(client); - request.setHost(u.getHost()); - request.setPath(u.getPath()); - request.setProtocol(u.getProtocol()); - request.setPort(u.getPort()); - return request; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - /** - * Returns a string's base64 encoding - * - * @param bytes - * @return base64 string - */ - public String toBase64(byte[] bytes) { - try { - return new String(Base64.encodeBase64(bytes), StandardCharsets.UTF_8).trim(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - -} +// +// private String createMultiPartBody() throws IOException { +// HttpEntity entity = MultipartEntityBuilder.create().addTextBody("textPart", "here is sample xml", ContentType.APPLICATION_XML).build(); +// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); +// entity.writeTo(byteArrayOutputStream); +// String ret = new String(byteArrayOutputStream.toByteArray()); +// +// System.out.println(ret); +// ret = toBase64(byteArrayOutputStream.toByteArray()); +// System.out.println(ret); +// return ret; +// } +// +// private BaseRequest getRequest(TankHttpClient client, String url) { +// try { +// URL u = new URL(url); +// client.setHttpClient(null); +// BaseRequest request = new MockBaseRequest(client); +// request.setHost(u.getHost()); +// request.setPath(u.getPath()); +// request.setProtocol(u.getProtocol()); +// request.setPort(u.getPort()); +// return request; +// } catch (Exception e) { +// e.printStackTrace(); +// throw new RuntimeException(e); +// } +// } +// +// /** +// * Returns a string's base64 encoding +// * +// * @param bytes +// * @return base64 string +// */ +// public String toBase64(byte[] bytes) { +// try { +// return new String(Base64.encodeBase64(bytes), StandardCharsets.UTF_8).trim(); +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// } +// +//} diff --git a/pom.xml b/pom.xml index de802d0b3..71071ecf1 100644 --- a/pom.xml +++ b/pom.xml @@ -848,6 +848,12 @@ org.springframework.boot spring-boot-starter-webflux + + + org.apache.logging.log4j + log4j-to-slf4j + + ${version.spring-webflux} diff --git a/rest-mvc/pom.xml b/rest-mvc/pom.xml index c289b87a1..a91228d0c 100644 --- a/rest-mvc/pom.xml +++ b/rest-mvc/pom.xml @@ -22,6 +22,10 @@ org.springframework spring-web + + org.springframework.boot + spring-boot-starter-webflux + org.springframework.boot spring-boot diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java index 3ad06a802..d02d15f80 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java @@ -16,7 +16,7 @@ import org.springframework.context.ConfigurableApplicationContext; @OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server URL")}) -@SpringBootApplication +@SpringBootApplication(proxyBeanMethods = false) public class TankAPIApplication extends SpringBootServletInitializer { public static ConfigurableApplicationContext run(String[] args) { return SpringApplication.run(TankAPIApplication.class, args); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java index d757f6986..463ceea39 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -9,7 +9,7 @@ import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentTestStartData; import com.intuit.tank.vm.agent.messages.AgentData; 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 d11370fa4..0cbaee1a3 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 @@ -8,6 +8,7 @@ package com.intuit.tank.rest.mvc.rest.services.agent; import com.intuit.tank.perfManager.workLoads.JobManager; +import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceBadRequestException; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; @@ -145,8 +146,8 @@ public AgentTestStartData agentReady(AgentData data) { JobManager jobManager = new ServletInjector().getManagedBean(servletContext, JobManager.class); response = jobManager.registerAgentForJob(data); } catch (Exception e) { - LOGGER.error("Error registering for a job: " + e.getMessage(), e); - throw new GenericServiceResourceNotFoundException("agent", "and registering agent", e); + LOGGER.error("Error registering agent for a job: " + e.getMessage(), e); + throw new GenericServiceBadRequestException("agent", "agent", "Error registering agent for a job with AgentData: " + data); } return response; } From 875e8f625149e8bc26e6678890e0062d4ae17bf4 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Tue, 6 Jun 2023 16:38:52 -0700 Subject: [PATCH 21/73] small clean up --- .../tank/rest/mvc/rest/clients/JobClient.java | 1 - .../mvc/rest/controllers/JobController.java | 2 +- .../intuit/tank/rest/RestUrlBuilderTest.java | 20 +++++++++---------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java index 57afc00f6..a2047ff00 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java @@ -11,7 +11,6 @@ import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; 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 bd0716980..bc5e3d385 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 @@ -148,7 +148,7 @@ public ResponseEntity getJobVMStatuses(@PathVariable @Pa return ResponseEntity.notFound().build(); } - @RequestMapping(value = "/script/{jobId}", method = RequestMethod.GET) + @RequestMapping(value = "/script/{jobId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_XML_VALUE }) @Operation(description = "Gets streaming output of job's harness XML file", summary = "Get job's harness file", hidden = true) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Successfully returned job's harness file", content = @Content), diff --git a/rest/client/common/src/test/java/com/intuit/tank/rest/RestUrlBuilderTest.java b/rest/client/common/src/test/java/com/intuit/tank/rest/RestUrlBuilderTest.java index e21be87ed..023d650c6 100644 --- a/rest/client/common/src/test/java/com/intuit/tank/rest/RestUrlBuilderTest.java +++ b/rest/client/common/src/test/java/com/intuit/tank/rest/RestUrlBuilderTest.java @@ -36,16 +36,16 @@ public class RestUrlBuilderTest { static Stream patterns() { return Stream.of( - Arguments.of("http://base.url.com/rest/v1", "method", "parameter", "http://base.url.com/rest/v1/method/parameter"), - Arguments.of("http://base.url.com/rest/v1/", "method", "parameter", "http://base.url.com/rest/v1/method/parameter"), - Arguments.of("http://base.url.com/rest/v1/", "/method", "parameter", "http://base.url.com/rest/v1/method/parameter"), - Arguments.of("http://base.url.com/rest/v1/", "/method/", "parameter", "http://base.url.com/rest/v1/method/parameter"), - Arguments.of("http://base.url.com/rest/v1/", "/method/", "/parameter", "http://base.url.com/rest/v1/method/parameter"), - Arguments.of("http://base.url.com/rest/v1/", "/method/", "/parameter/", "http://base.url.com/rest/v1/method/parameter/"), - Arguments.of("http://base.url.com/rest/v1", "method", null, "http://base.url.com/rest/v1/method"), - Arguments.of("http://base.url.com/rest/v1", "/method", null, "http://base.url.com/rest/v1/method"), - Arguments.of("http://base.url.com/rest/v1", "/method/", null, "http://base.url.com/rest/v1/method"), - Arguments.of("http://base.url.com/rest/v1", null, null, "http://base.url.com/rest/v1") + Arguments.of("http://base.url.com/api/v2", "method", "parameter", "http://base.url.com/api/v2/method/parameter"), + Arguments.of("http://base.url.com/api/v2/", "method", "parameter", "http://base.url.com/api/v2/method/parameter"), + Arguments.of("http://base.url.com/api/v2/", "/method", "parameter", "http://base.url.com/api/v2/method/parameter"), + Arguments.of("http://base.url.com/api/v2/", "/method/", "parameter", "http://base.url.com/api/v2/method/parameter"), + Arguments.of("http://base.url.com/api/v2/", "/method/", "/parameter", "http://base.url.com/api/v2/method/parameter"), + Arguments.of("http://base.url.com/api/v2/", "/method/", "/parameter/", "http://base.url.com/api/v2/method/parameter/"), + Arguments.of("http://base.url.com/api/v2", "method", null, "http://base.url.com/api/v2/method"), + Arguments.of("http://base.url.com/api/v2", "/method", null, "http://base.url.com/api/v2/method"), + Arguments.of("http://base.url.com/api/v2", "/method/", null, "http://base.url.com/api/v2/method"), + Arguments.of("http://base.url.com/api/v2", null, null, "http://base.url.com/api/v2") ); } From 9287885aa80d3724fa6a6c6767eafe43e07c2df5 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Wed, 7 Jun 2023 09:41:35 -0700 Subject: [PATCH 22/73] dep injection fix --- .../tank/rest/mvc/TankAPIApplication.java | 8 +++++ .../rest/models/common/cloud/VMTracker.java | 4 +-- .../rest/mvc/rest/util/JobEventListener.java | 31 ++++++++++--------- .../rest/mvc/rest/util/JobEventSender.java | 20 ++++++------ .../rest/mvc/rest/util/ServletInjector.java | 2 -- .../src/main/resources/META-INF/beans.xml | 2 +- .../v1/automation/AutomationServiceV1.java | 4 +-- .../intuit/tank/ProjectDescriptionBean.java | 2 ++ web/web_ui/src/main/webapp/docs/index.xhtml | 2 +- 9 files changed, 42 insertions(+), 33 deletions(-) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java index d02d15f80..08bd0e8ac 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java @@ -7,16 +7,24 @@ */ package com.intuit.tank.rest.mvc; +import com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTrackerV2Impl; +import com.intuit.tank.rest.mvc.rest.util.JobEventListener; +import com.intuit.tank.rest.mvc.rest.util.JobEventSender; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.servers.Server; import org.springframework.boot.SpringApplication; +import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.FilterType; @OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server URL")}) @SpringBootApplication(proxyBeanMethods = false) +@ComponentScan(basePackages = "com.intuit.tank.rest.mvc", excludeFilters = { + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JobEventSender.class, JobEventListener.class, VMTrackerV2Impl.class}) +}) public class TankAPIApplication extends SpringBootServletInitializer { public static ConfigurableApplicationContext run(String[] args) { return SpringApplication.run(TankAPIApplication.class, args); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java index 1cb275f3b..b2cced97d 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java @@ -11,12 +11,12 @@ import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.common.ProjectStatusContainer; import com.intuit.tank.vm.event.JobEvent; -import org.springframework.stereotype.Component; +import javax.inject.Named; import javax.annotation.Nonnull; import java.util.Set; -@Component +@Named public interface VMTracker { /** diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java index feb82735a..8db1beb6b 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java @@ -7,34 +7,35 @@ */ package com.intuit.tank.rest.mvc.rest.util; -import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; -import com.intuit.tank.vm.event.JobEvent; +import java.io.Serializable; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.inject.Named; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.springframework.web.context.annotation.ApplicationScope; -import org.springframework.context.event.EventListener; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import java.io.Serializable; -@Service -@ApplicationScope +import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; +import com.intuit.tank.vm.event.JobEvent; + +@Named +@ApplicationScoped public class JobEventListener implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOG = LogManager.getLogger(JobEventListener.class); - @Autowired - private ObjectProvider controllerSource; + @Inject + private Instance controllerSource; - @EventListener - public void observerJobKillRequest(JobEvent request) { + public void observerJobKillRequest(@Observes JobEvent request) { LOG.info("Got Job Event: " + request); if (request.getEvent() == JobLifecycleEvent.JOB_ABORTED) { - controllerSource.getIfAvailable().killJob(request.getJobId(), false); + controllerSource.get().killJob(request.getJobId(), false); } } } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java index 242e26c3a..da3f12455 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java @@ -33,32 +33,32 @@ import org.apache.commons.lang3.math.NumberUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.context.annotation.RequestScope; -import org.springframework.stereotype.Service; +import javax.enterprise.context.RequestScoped; import javax.enterprise.event.Event; +import javax.inject.Inject; +import javax.inject.Named; import java.util.*; import java.util.stream.Collectors; -@Service -@RequestScope +@Named +@RequestScoped public class JobEventSender { private static final Logger LOG = LogManager.getLogger(JobEventSender.class); - @Autowired + @Inject private VMTracker vmTracker; - @Autowired + @Inject private VMTerminator terminator; - @Autowired + @Inject private JobManager jobManager; - @Autowired + @Inject private AgentChannel agentChannel; - @Autowired + @Inject private Event jobEventProducer; public String startJob(String jobId) { diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java index ca31b48eb..0d72083c4 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java @@ -10,10 +10,8 @@ import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; -import org.springframework.stereotype.Service; import javax.servlet.ServletContext; -@Service public class ServletInjector { private BeanManager getBeanManager(ServletContext servletContext) { diff --git a/rest-mvc/src/main/resources/META-INF/beans.xml b/rest-mvc/src/main/resources/META-INF/beans.xml index 16ab4cdff..dd8f35fb2 100644 --- a/rest-mvc/src/main/resources/META-INF/beans.xml +++ b/rest-mvc/src/main/resources/META-INF/beans.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" bean-discovery-mode="all"> - + com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTrackerV2Impl diff --git a/rest/service/automation/src/main/java/com/intuit/tank/service/impl/v1/automation/AutomationServiceV1.java b/rest/service/automation/src/main/java/com/intuit/tank/service/impl/v1/automation/AutomationServiceV1.java index e3895f074..6353aafdf 100644 --- a/rest/service/automation/src/main/java/com/intuit/tank/service/impl/v1/automation/AutomationServiceV1.java +++ b/rest/service/automation/src/main/java/com/intuit/tank/service/impl/v1/automation/AutomationServiceV1.java @@ -77,11 +77,11 @@ import com.intuit.tank.project.DataFile; import com.intuit.tank.project.EntityVersion; import com.intuit.tank.project.JobConfiguration; -import com.intuit.tank.rest.mvc.rest.util.JobDetailFormatter; +import com.intuit.tank.project.JobDetailFormatter; import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.JobQueue; import com.intuit.tank.project.JobRegion; -import com.intuit.tank.rest.mvc.rest.util.JobValidator; +import com.intuit.tank.project.JobValidator; import com.intuit.tank.project.Project; import com.intuit.tank.project.Script; import com.intuit.tank.project.ScriptFilter; diff --git a/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java b/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java index 57dc576f3..d7d3c5653 100644 --- a/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java @@ -68,6 +68,8 @@ public class ProjectDescriptionBean extends SelectableBean implements S public void init() { tablePrefs = new TablePreferences(userPrefs.getPreferences().getProjectTableColumns()); tablePrefs.registerListener(userPrefs); + messages.warn("Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + + "please download the newest version of Tank tools under the Tools tab. Refer to the API documentation under Help for more details."); } public void deleteSelectedProject() { diff --git a/web/web_ui/src/main/webapp/docs/index.xhtml b/web/web_ui/src/main/webapp/docs/index.xhtml index 042287621..924a0d2cc 100644 --- a/web/web_ui/src/main/webapp/docs/index.xhtml +++ b/web/web_ui/src/main/webapp/docs/index.xhtml @@ -41,7 +41,7 @@
- +
Rest V2 API documentation From 59ba28572d712dcd00d41afc4dda2db3807c5a3b Mon Sep 17 00:00:00 2001 From: zkofiro Date: Wed, 7 Jun 2023 13:15:43 -0700 Subject: [PATCH 23/73] need to shorten V2 url due to dep inj fix --- .../agent/StandaloneAgentStartup.java | 2 +- .../com/intuit/tank/agent/AgentStartup.java | 2 +- .../v1/project/ProjectServiceUrlBuilder.java | 2 +- .../project/ProjectServiceUrlBuilderTest.java | 2 +- .../com/intuit/tank/util/DataFileUtil.java | 2 +- .../intuit/tank/util/DataFileUtilTest.java | 2 +- .../rest/mvc/rest/clients/AgentClient.java | 2 +- .../rest/mvc/rest/clients/DataFileClient.java | 2 +- .../rest/mvc/rest/clients/FilterClient.java | 2 +- .../tank/rest/mvc/rest/clients/JobClient.java | 2 +- .../rest/mvc/rest/clients/ProjectClient.java | 2 +- .../rest/mvc/rest/clients/ScriptClient.java | 2 +- .../rest/controllers/DataFileController.java | 6 +- .../rest/controllers/ScriptController.java | 6 +- .../models/common/cloud/VMTrackerV2Impl.java | 358 ++++++++++++++++++ .../mvc/rest/util/DataFileServiceUtil.java | 2 +- .../intuit/tank/rest/RestUrlBuilderTest.java | 20 +- .../intuit/tank/project/DataFileBrowser.java | 2 +- 18 files changed, 388 insertions(+), 30 deletions(-) create mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java diff --git a/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java b/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java index 73d31942c..60ef6009d 100644 --- a/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java +++ b/agent/agent_standalone/src/main/java/com/intuit/tank/standalone/agent/StandaloneAgentStartup.java @@ -37,7 +37,7 @@ public class StandaloneAgentStartup implements Runnable { private static Logger LOG = LogManager.getLogger(StandaloneAgentStartup.class); - public static final String SERVICE_RELATIVE_PATH = "/api/v2/agent"; + public static final String SERVICE_RELATIVE_PATH = "/v2/agent"; private static String API_HARNESS_COMMAND = "./startAgent.sh"; public static final String METHOD_SETTINGS = "/settings"; public static final String METHOD_SUPPORT = "/support-files"; diff --git a/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java b/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java index ad76a7e08..57bd73214 100644 --- a/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java +++ b/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java @@ -34,7 +34,7 @@ public class AgentStartup implements Runnable { private static final Logger logger = LogManager.getLogger(AgentStartup.class); - private static final String SERVICE_RELATIVE_PATH = "/api/v2/agent"; + private static final String SERVICE_RELATIVE_PATH = "/v2/agent"; private static final String METHOD_SETTINGS = "/settings"; private static final String API_HARNESS_COMMAND = "./startAgent.sh"; private static final String METHOD_SUPPORT = "/support-files"; diff --git a/api/src/main/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilder.java b/api/src/main/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilder.java index 73af35bd1..a8b864872 100644 --- a/api/src/main/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilder.java +++ b/api/src/main/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilder.java @@ -39,7 +39,7 @@ private ProjectServiceUrlBuilder() { */ public static String getScriptXmlUrl(String jobId) { String baseUrl = new TankConfig().getControllerBase(); - return baseUrl + "/api/v2/jobs/script/" + jobId; + return baseUrl + "/v2/jobs/script/" + jobId; } } diff --git a/api/src/test/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilderTest.java b/api/src/test/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilderTest.java index 6c220c69d..eeb55590a 100644 --- a/api/src/test/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilderTest.java +++ b/api/src/test/java/com/intuit/tank/vm/api/service/v1/project/ProjectServiceUrlBuilderTest.java @@ -31,6 +31,6 @@ public class ProjectServiceUrlBuilderTest { @Tag(TestGroups.FUNCTIONAL) public void testGetScriptXmlUrl() throws Exception { assertEquals(ProjectServiceUrlBuilder.getScriptXmlUrl("1"), new TankConfig().getControllerBase() - + "/api/v2/jobs/script/1"); + + "/v2/jobs/script/1"); } } diff --git a/data_model/src/main/java/com/intuit/tank/util/DataFileUtil.java b/data_model/src/main/java/com/intuit/tank/util/DataFileUtil.java index e72661659..11c13766e 100644 --- a/data_model/src/main/java/com/intuit/tank/util/DataFileUtil.java +++ b/data_model/src/main/java/com/intuit/tank/util/DataFileUtil.java @@ -43,7 +43,7 @@ private DataFileUtil() { */ public static String getDataFileServiceUrl(int id, int offSet, int numLines) { String baseUrl = new TankConfig().getControllerBase(); - return baseUrl + "/api/v2/datafiles/content?id=" + id + "&offset=" + offSet + "&lines=" + numLines; + return baseUrl + "/v2/datafiles/content?id=" + id + "&offset=" + offSet + "&lines=" + numLines; } /** diff --git a/data_model/src/test/java/com/intuit/tank/util/DataFileUtilTest.java b/data_model/src/test/java/com/intuit/tank/util/DataFileUtilTest.java index 67aa4cad8..bbfdc687a 100644 --- a/data_model/src/test/java/com/intuit/tank/util/DataFileUtilTest.java +++ b/data_model/src/test/java/com/intuit/tank/util/DataFileUtilTest.java @@ -30,7 +30,7 @@ public class DataFileUtilTest { @Test public void testGetDataFileServiceUrl() { - String expected = "http://localhost:8080/tank/api/v2/datafiles/content?id=2&offset=4&lines=10"; + String expected = "http://localhost:8080/tank/v2/datafiles/content?id=2&offset=4&lines=10"; assertEquals(expected, DataFileUtil.getDataFileServiceUrl(2, 4, 10)); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java index 463ceea39..8a33555ee 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -24,7 +24,7 @@ public class AgentClient extends BaseClient{ - private static final String SERVICE_BASE_URL = "/api/v2/agent"; + private static final String SERVICE_BASE_URL = "/v2/agent"; public AgentClient(String serviceUrl) { super(serviceUrl, null, null); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java index 34eced2a2..6aa76ea6d 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/DataFileClient.java @@ -21,7 +21,7 @@ public class DataFileClient extends BaseClient{ - private static final String SERVICE_BASE_URL = "/api/v2/datafiles"; + private static final String SERVICE_BASE_URL = "/v2/datafiles"; public DataFileClient(String serviceUrl) { super(serviceUrl, null, null); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java index 6c5371dbe..8c574c37a 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/FilterClient.java @@ -17,7 +17,7 @@ public class FilterClient extends BaseClient{ - private static final String SERVICE_BASE_URL = "/api/v2/filters"; + private static final String SERVICE_BASE_URL = "/v2/filters"; public FilterClient(String serviceUrl) { super(serviceUrl, null, null); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java index a2047ff00..40b0e0446 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/JobClient.java @@ -19,7 +19,7 @@ public class JobClient extends BaseClient{ - private static final String SERVICE_BASE_URL = "/api/v2/jobs"; + private static final String SERVICE_BASE_URL = "/v2/jobs"; public JobClient(String serviceUrl) { super(serviceUrl, null, null); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java index ff7c9ed8c..7c1104e2b 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java @@ -24,7 +24,7 @@ public class ProjectClient extends BaseClient{ - private static final String SERVICE_BASE_URL = "/api/v2/projects"; + private static final String SERVICE_BASE_URL = "/v2/projects"; public ProjectClient(String serviceUrl) { super(serviceUrl, null, null); diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java index 5797e11ad..7d163ef83 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java @@ -24,7 +24,7 @@ public class ScriptClient extends BaseClient{ - private static final String SERVICE_BASE_URL = "/api/v2/scripts"; + private static final String SERVICE_BASE_URL = "/v2/scripts"; public ScriptClient(String serviceUrl) { super(serviceUrl, null, null); 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 a72200b66..74f59f5b2 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 @@ -127,12 +127,12 @@ public ResponseEntity downloadDatafile(@PathVariable @Par @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) @Operation(description = "Uploads a datafile to Tank (supports gzip files) \n\n " + "Examples: \n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/datafiles/upload'\n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/v2/datafiles/upload'\n\n" + "\n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/datafiles/upload?id='\n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/v2/datafiles/upload?id='\n\n" + "\n\n" + " gzip \n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -H 'Content-Encoding: gzip' -F \"file=@.gz\" 'https://{tank-base-url}/api/v2/datafiles/upload'\n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -H 'Content-Encoding: gzip' -F \"file=@.gz\" 'https://{tank-base-url}/v2/datafiles/upload'\n\n" + "Notes: \n\n " + " - Datafile id is an optional parameter \n\n" + " - Passing in an existing Tank Datafile ID will overwrite the existing datafile in Tank, but will otherwise create a new datafile", summary = "Upload datafile to Tank") 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 8a270b7f8..5c34bfdfc 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 @@ -151,12 +151,12 @@ public ResponseEntity downloadHarnessScript(@PathVariable @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) @Operation(description = "Uploads a script XML file output generated by the Tank Proxy Package (supports gzip files) \n\n " + "Examples: \n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/scripts/upload' \n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/v2/scripts/upload' \n\n" + "\n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/api/v2/scripts/upload?id=&name='\n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -F \"file=@\" 'https://{tank-base-url}/v2/scripts/upload?id=&name='\n\n" + "\n\n" + " gzip \n\n" + - " curl -v -X POST -H 'Content-Type: multipart/form-data' -H 'Content-Encoding: gzip' -F \"file=@.gz\" 'https://{tank-base-url}/api/v2/scripts/upload'\n\n" + + " curl -v -X POST -H 'Content-Type: multipart/form-data' -H 'Content-Encoding: gzip' -F \"file=@.gz\" 'https://{tank-base-url}/v2/scripts/upload'\n\n" + "Notes: \n\n " + " - This endpoint only accepts XML script file recorded and produced by the Tank Proxy Package (see Tools tab in Tank)\n\n" + " - Both script name and script id are optional parameters \n\n" + diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java new file mode 100644 index 000000000..0a28dc9a8 --- /dev/null +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java @@ -0,0 +1,358 @@ +/** + * Copyright 2015-2023 Intuit Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.intuit.tank.rest.mvc.rest.models.common.cloud; + + +import com.amazonaws.xray.AWSXRay; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; +import com.intuit.tank.rest.mvc.rest.models.common.ProjectStatusContainer; +import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; +import com.intuit.tank.dao.JobInstanceDao; +import com.intuit.tank.dao.WorkloadDao; +import com.intuit.tank.project.JobInstance; +import com.intuit.tank.project.Workload; +import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; +import com.intuit.tank.vm.api.enumerated.JobQueueStatus; +import com.intuit.tank.vm.api.enumerated.JobStatus; +import com.intuit.tank.vm.common.TankConstants; +import com.intuit.tank.vm.event.JobEvent; +import com.intuit.tank.vm.settings.TankConfig; +import com.intuit.tank.vmManager.environment.amazon.AmazonInstance; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.annotation.Nonnull; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Event; +import javax.enterprise.inject.Instance; +import javax.enterprise.inject.Alternative; +import javax.inject.Inject; +import javax.inject.Named; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.*; + +import static com.intuit.tank.vm.common.TankConstants.NOTIFICATIONS_EVENT_EVENT_TIME_KEY; + +@Named +@ApplicationScoped +@Alternative +public class VMTrackerV2Impl implements VMTracker { + private static final Logger LOG = LogManager.getLogger(VMTrackerV2Impl.class); + + private ConcurrentMap locks = new ConcurrentHashMap(); + private boolean devMode = false; + + @Inject + private Event jobEventProducer; + + @Inject + private Instance jobInstanceDao; + + @Inject + private Instance workloadDaoInstance; + + private Map jobToProjectIdMap = new ConcurrentHashMap(); + private Map projectContainerMap = new ConcurrentHashMap(); + private Map statusMap = new ConcurrentHashMap(); + private Map jobMap = new ConcurrentHashMap(); + private Set stoppedJobs = new HashSet(); + + private static final ThreadPoolExecutor EXECUTOR = + new ThreadPoolExecutor(10, 50, 60, TimeUnit.SECONDS, + new ArrayBlockingQueue(50), + threadFactoryRunnable -> { + Thread t = Executors.defaultThreadFactory().newThread(threadFactoryRunnable); + t.setDaemon(true); + return t; + }, + new ThreadPoolExecutor.DiscardOldestPolicy()); + + /** + * + */ + @PostConstruct + public void init() { + devMode = new TankConfig().getStandalone(); + } + + /** + * {@inheritDoc} + */ + @Override + public CloudVmStatus getStatus(@Nonnull String instanceId) { + return statusMap.get(instanceId); + } + + public ProjectStatusContainer getProjectStatusContainer(String projectId) { + return projectContainerMap.get(projectId); + } + + /** + * {@inheritDoc} + */ + @Override + public void publishEvent(JobEvent event) { + try { + jobEventProducer.fire(event); + } catch (Exception e) { + LOG.error("Error firing Event: " + e, e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setStatus(@Nonnull final CloudVmStatus status) { + Runnable task = () -> setStatusThread(status); + AWSXRay.createSubsegment("Update.Status", task); //initiation call has already returned 204 + EXECUTOR.execute(task); + } + + private void setStatusThread(@Nonnull final CloudVmStatus status) { + synchronized (getCacheSyncObject(status.getJobId())) { + status.setReportTime(new Date()); + CloudVmStatus currentStatus = getStatus(status.getInstanceId()); + if (shouldUpdateStatus(currentStatus)) { + statusMap.put(status.getInstanceId(), status); + if (status.getVmStatus() == VMStatus.running + && (status.getJobStatus() == JobStatus.Completed) + && !isDevMode()) { + AmazonInstance amzInstance = new AmazonInstance(status.getVmRegion()); + amzInstance.killInstances(Collections.singletonList(status.getInstanceId())); + } + } + String jobId = status.getJobId(); + CloudVmStatusContainer cloudVmStatusContainer = jobMap.get(jobId); + if (cloudVmStatusContainer == null) { + cloudVmStatusContainer = new CloudVmStatusContainer(); + cloudVmStatusContainer.setJobId(jobId); + + jobMap.put(jobId, cloudVmStatusContainer); + JobInstance job = jobInstanceDao.get().findById(Integer.parseInt(jobId)); + if (job != null) { + JobQueueStatus newStatus = getQueueStatus(job.getStatus(), status.getJobStatus()); + cloudVmStatusContainer.setStatus(newStatus); + if (newStatus != job.getStatus()) { + job.setStatus(newStatus); + new JobInstanceDao().saveOrUpdate(job); + } + } else { + JobQueueStatus newStatus = getQueueStatus(cloudVmStatusContainer.getStatus(), status.getJobStatus()); + cloudVmStatusContainer.setStatus(newStatus); + } + } + cloudVmStatusContainer.setReportTime(status.getReportTime()); + addStatusToJobContainer(status, cloudVmStatusContainer); + String projectId = getProjectForJobId(jobId); + if (projectId != null) { + ProjectStatusContainer projectStatusContainer = getProjectStatusContainer(projectId); + if (projectStatusContainer == null) { + projectStatusContainer = new ProjectStatusContainer(); + projectContainerMap.put(projectId, projectStatusContainer); + } + projectStatusContainer.addStatusContainer(cloudVmStatusContainer); + } + } + } + + private String getProjectForJobId(String jobId) { + String ret = jobToProjectIdMap.get(jobId); + if (ret == null) { + try { + JobInstance jobInstance = jobInstanceDao.get().findById(Integer.valueOf(jobId)); + Workload wkld = workloadDaoInstance.get().findById(jobInstance.getWorkloadId()); + ret = Integer.toString(wkld.getProject().getId()); + } catch (Exception e) { + LOG.error("cannot get projectId for jobId " + jobId + ": " + e.toString(), e); + ret = ""; + } + jobToProjectIdMap.put(jobId, ret); + } + return StringUtils.isNotBlank(ret) ? ret : null; + } + + /** + * @param oldStatus + * @param jobStatus + * @return + */ + private JobQueueStatus getQueueStatus(JobQueueStatus oldStatus, JobStatus jobStatus) { + try { + return JobQueueStatus.valueOf(jobStatus.name()); + } catch (Exception e) { + LOG.error("Error converting status from " + jobStatus); + } + return oldStatus; + } + + /** + * If the vm is shutting down or terminated, don't update the status to something else. + * @param currentStatus + * @return + */ + private boolean shouldUpdateStatus(CloudVmStatus currentStatus) { + if (currentStatus != null) { + VMStatus status = currentStatus.getVmStatus(); + return (status != VMStatus.shutting_down + && status != VMStatus.stopped + && status != VMStatus.stopping + && status != VMStatus.terminated); + } + return true; + } + + /** + * + * {@inheritDoc} + */ + @Override + public void removeStatusForInstance(String instanceId) { + statusMap.remove(instanceId); + } + + /** + * + * {@inheritDoc} + */ + @Override + public void removeStatusForJob(String jobId) { + CloudVmStatusContainer cloudVmStatusContainer = jobMap.get(jobId); + if (cloudVmStatusContainer != null) { + for (CloudVmStatus s : cloudVmStatusContainer.getStatuses()) { + removeStatusForInstance(s.getInstanceId()); + } + jobMap.remove(jobId); + } + } + + /** + * {@inheritDoc} + */ + @Override + public CloudVmStatusContainer getVmStatusForJob(String jobId) { + return jobMap.get(jobId); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isDevMode() { + return devMode; + } + + /** + * {@inheritDoc} + */ + @Override + public Set getAllJobs() { + return new HashSet(jobMap.values()); + } + + @Override + public boolean isRunning(String id) { + return !stoppedJobs.contains(id); + } + + @Override + public void stopJob(String id) { + stoppedJobs.add(id); + } + + /** + * @param status + * @param cloudVmStatusContainer + **/ + private void addStatusToJobContainer(CloudVmStatus status, CloudVmStatusContainer cloudVmStatusContainer) { + cloudVmStatusContainer.getStatuses().remove(status); + cloudVmStatusContainer.getStatuses().add(status); + cloudVmStatusContainer.calculateUserDetails(); + boolean isFinished = true; + boolean paused = true; + boolean rampPaused = true; + boolean stopped = true; + boolean running = true; + + // look up the job + JobInstance job = jobInstanceDao.get().findById(Integer.parseInt(status.getJobId())); + for (CloudVmStatus s : cloudVmStatusContainer.getStatuses()) { + JobStatus jobStatus = s.getJobStatus(); + if (jobStatus != JobStatus.Completed) { // If no VMs are Completed + isFinished = false; + } + if (jobStatus != JobStatus.Paused) { // If no VMs are Paused + paused = false; + } + if (jobStatus != JobStatus.RampPaused) { // If no VMs are RampPaused + rampPaused = false; + } + if (jobStatus != JobStatus.Stopped) { // If no VMs are Stopped + stopped = false; + } + if (jobStatus != JobStatus.Running) { // If no VMs are Running + running = false; + } + } + if (isFinished) { + LOG.info("Setting end time on container " + cloudVmStatusContainer.getJobId()); + if (cloudVmStatusContainer.getEndTime() == null) { + jobEventProducer.fire(new JobEvent(status.getJobId(), "", JobLifecycleEvent.JOB_FINISHED) + .addContextEntry(NOTIFICATIONS_EVENT_EVENT_TIME_KEY, + new SimpleDateFormat(TankConstants.DATE_FORMAT_WITH_TIMEZONE).format(new Date()))); + } + cloudVmStatusContainer.setEndTime(new Date()); + } + if (job != null) { + job.setEndTime(cloudVmStatusContainer.getEndTime()); + JobQueueStatus newStatus = job.getStatus(); + if (isFinished) { + newStatus = JobQueueStatus.Completed; + stopJob(Integer.toString(job.getId())); + } else if (paused) { + newStatus = JobQueueStatus.Paused; + } else if (rampPaused) { + newStatus = JobQueueStatus.RampPaused; + } else if (stopped) { + newStatus = JobQueueStatus.Stopped; + } else if (running) { + newStatus = JobQueueStatus.Running; + if (job.getStartTime() == null && status.getJobStatus() == JobStatus.Running) { + job.setStartTime(status.getStartTime()); + jobEventProducer.fire(new JobEvent(Integer.toString(job.getId()), "", JobLifecycleEvent.LOAD_STARTED)); + } + } + + LOG.trace("Setting Container for job=" + status.getJobId() + " newStatus to " + newStatus); + job.setStatus(newStatus); + jobInstanceDao.get().saveOrUpdate(job); + + // Job StartTime is source of truth for cloudVMStatusContainer StartTime + if (job.getStartTime() != null && cloudVmStatusContainer.getStartTime() != null) { + if (job.getStartTime().before(cloudVmStatusContainer.getStartTime())) { + cloudVmStatusContainer.setStartTime(job.getStartTime()); + } + } + } + } + + private Object getCacheSyncObject(final String id) { + locks.putIfAbsent(id, id); + return locks.get(id); + } + + @PreDestroy + private void destroy() { + EXECUTOR.shutdown(); + } +} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java index c4ed0f9a8..b9a2c183c 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/DataFileServiceUtil.java @@ -40,7 +40,7 @@ public static DataFileDescriptor dataFileToDescriptor(DataFile dataFile) { } private static String getRelativeDataUrl(int id) { - String url = config.getControllerBase() + "/api/v2/datafiles/content?id={id}"; + String url = config.getControllerBase() + "/v2/datafiles/content?id={id}"; return url.replace("{id}", Integer.toString(id)); } diff --git a/rest/client/common/src/test/java/com/intuit/tank/rest/RestUrlBuilderTest.java b/rest/client/common/src/test/java/com/intuit/tank/rest/RestUrlBuilderTest.java index 023d650c6..bd85a0a3a 100644 --- a/rest/client/common/src/test/java/com/intuit/tank/rest/RestUrlBuilderTest.java +++ b/rest/client/common/src/test/java/com/intuit/tank/rest/RestUrlBuilderTest.java @@ -36,16 +36,16 @@ public class RestUrlBuilderTest { static Stream patterns() { return Stream.of( - Arguments.of("http://base.url.com/api/v2", "method", "parameter", "http://base.url.com/api/v2/method/parameter"), - Arguments.of("http://base.url.com/api/v2/", "method", "parameter", "http://base.url.com/api/v2/method/parameter"), - Arguments.of("http://base.url.com/api/v2/", "/method", "parameter", "http://base.url.com/api/v2/method/parameter"), - Arguments.of("http://base.url.com/api/v2/", "/method/", "parameter", "http://base.url.com/api/v2/method/parameter"), - Arguments.of("http://base.url.com/api/v2/", "/method/", "/parameter", "http://base.url.com/api/v2/method/parameter"), - Arguments.of("http://base.url.com/api/v2/", "/method/", "/parameter/", "http://base.url.com/api/v2/method/parameter/"), - Arguments.of("http://base.url.com/api/v2", "method", null, "http://base.url.com/api/v2/method"), - Arguments.of("http://base.url.com/api/v2", "/method", null, "http://base.url.com/api/v2/method"), - Arguments.of("http://base.url.com/api/v2", "/method/", null, "http://base.url.com/api/v2/method"), - Arguments.of("http://base.url.com/api/v2", null, null, "http://base.url.com/api/v2") + Arguments.of("http://base.url.com/v2", "method", "parameter", "http://base.url.com/v2/method/parameter"), + Arguments.of("http://base.url.com/v2/", "method", "parameter", "http://base.url.com/v2/method/parameter"), + Arguments.of("http://base.url.com/v2/", "/method", "parameter", "http://base.url.com/v2/method/parameter"), + Arguments.of("http://base.url.com/v2/", "/method/", "parameter", "http://base.url.com/v2/method/parameter"), + Arguments.of("http://base.url.com/v2/", "/method/", "/parameter", "http://base.url.com/v2/method/parameter"), + Arguments.of("http://base.url.com/v2/", "/method/", "/parameter/", "http://base.url.com/v2/method/parameter/"), + Arguments.of("http://base.url.com/v2", "method", null, "http://base.url.com/v2/method"), + Arguments.of("http://base.url.com/v2", "/method", null, "http://base.url.com/v2/method"), + Arguments.of("http://base.url.com/v2", "/method/", null, "http://base.url.com/v2/method"), + Arguments.of("http://base.url.com/v2", null, null, "http://base.url.com/v2") ); } diff --git a/web/web_support/src/main/java/com/intuit/tank/project/DataFileBrowser.java b/web/web_support/src/main/java/com/intuit/tank/project/DataFileBrowser.java index e6aeebcb2..61181f404 100644 --- a/web/web_support/src/main/java/com/intuit/tank/project/DataFileBrowser.java +++ b/web/web_support/src/main/java/com/intuit/tank/project/DataFileBrowser.java @@ -289,7 +289,7 @@ public void jumpToInputPage() { public String getDataFileDownloadLink(DataFile dataFile) { TankConfig config = new TankConfig(); if (dataFile != null) { - String url = config.getControllerBase() + "/api/v2/datafiles/download/{id}"; + String url = config.getControllerBase() + "/v2/datafiles/download/{id}"; return url.replace("{id}", Integer.toString(dataFile.getId())); } else { return ""; From f587553007ee82591ded8b5ea89a8d97642f72ba Mon Sep 17 00:00:00 2001 From: zkofiro Date: Wed, 7 Jun 2023 23:45:51 -0700 Subject: [PATCH 24/73] missing dependency --- proxy-parent/owasp-proxy/pom.xml | 5 +++++ rest-mvc/pom.xml | 5 +++++ .../intuit/tank/rest/mvc/TankAPIApplication.java | 12 ++---------- web/web_ui/src/main/webapp/META-INF/context.xml | 13 +++++++++++++ 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml index 3299f5e5f..42064e1c8 100755 --- a/proxy-parent/owasp-proxy/pom.xml +++ b/proxy-parent/owasp-proxy/pom.xml @@ -96,6 +96,11 @@ 0.1.2 + + org.springframework + spring-dao + 2.0.8 + diff --git a/rest-mvc/pom.xml b/rest-mvc/pom.xml index a91228d0c..5edae88cb 100644 --- a/rest-mvc/pom.xml +++ b/rest-mvc/pom.xml @@ -41,6 +41,11 @@ script-engine ${project.version} + + ${project.groupId} + api + ${project.version} + ${project.groupId} data-access diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java index 08bd0e8ac..231a2e8f5 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java @@ -7,24 +7,16 @@ */ package com.intuit.tank.rest.mvc; -import com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTrackerV2Impl; -import com.intuit.tank.rest.mvc.rest.util.JobEventListener; -import com.intuit.tank.rest.mvc.rest.util.JobEventSender; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.servers.Server; import org.springframework.boot.SpringApplication; -import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.FilterType; -@OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server URL")}) -@SpringBootApplication(proxyBeanMethods = false) -@ComponentScan(basePackages = "com.intuit.tank.rest.mvc", excludeFilters = { - @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JobEventSender.class, JobEventListener.class, VMTrackerV2Impl.class}) -}) +@OpenAPIDefinition(servers = {@Server(url = "/tank_war", description = "Default Server URL")}) +@SpringBootApplication public class TankAPIApplication extends SpringBootServletInitializer { public static ConfigurableApplicationContext run(String[] args) { return SpringApplication.run(TankAPIApplication.class, args); diff --git a/web/web_ui/src/main/webapp/META-INF/context.xml b/web/web_ui/src/main/webapp/META-INF/context.xml index 6517d08d0..2fb659b00 100644 --- a/web/web_ui/src/main/webapp/META-INF/context.xml +++ b/web/web_ui/src/main/webapp/META-INF/context.xml @@ -5,5 +5,18 @@ auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> + From b3e268d0497abc39fd893eb0c694a4c86ebe3439 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Thu, 8 Jun 2023 00:28:23 -0700 Subject: [PATCH 25/73] unneeded files --- proxy-parent/owasp-proxy/pom.xml | 5 ----- .../intuit/tank/rest/mvc/TankAPIApplication.java | 12 ++++++++++-- web/web_ui/src/main/webapp/META-INF/context.xml | 13 ------------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml index 42064e1c8..3299f5e5f 100755 --- a/proxy-parent/owasp-proxy/pom.xml +++ b/proxy-parent/owasp-proxy/pom.xml @@ -96,11 +96,6 @@ 0.1.2 - - org.springframework - spring-dao - 2.0.8 - diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java index 231a2e8f5..08bd0e8ac 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java @@ -7,16 +7,24 @@ */ package com.intuit.tank.rest.mvc; +import com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTrackerV2Impl; +import com.intuit.tank.rest.mvc.rest.util.JobEventListener; +import com.intuit.tank.rest.mvc.rest.util.JobEventSender; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.servers.Server; import org.springframework.boot.SpringApplication; +import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.FilterType; -@OpenAPIDefinition(servers = {@Server(url = "/tank_war", description = "Default Server URL")}) -@SpringBootApplication +@OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server URL")}) +@SpringBootApplication(proxyBeanMethods = false) +@ComponentScan(basePackages = "com.intuit.tank.rest.mvc", excludeFilters = { + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JobEventSender.class, JobEventListener.class, VMTrackerV2Impl.class}) +}) public class TankAPIApplication extends SpringBootServletInitializer { public static ConfigurableApplicationContext run(String[] args) { return SpringApplication.run(TankAPIApplication.class, args); diff --git a/web/web_ui/src/main/webapp/META-INF/context.xml b/web/web_ui/src/main/webapp/META-INF/context.xml index 2fb659b00..6517d08d0 100644 --- a/web/web_ui/src/main/webapp/META-INF/context.xml +++ b/web/web_ui/src/main/webapp/META-INF/context.xml @@ -5,18 +5,5 @@ auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> - From e0724222d94322fc8d6f536ec39a6951f3f38eb7 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Thu, 8 Jun 2023 14:42:43 -0700 Subject: [PATCH 26/73] reverting cloud models until move away from Java EE CDI --- .../com/intuit/tank/harness/APIMonitor.java | 6 +-- .../intuit/tank/harness/APITestHarness.java | 6 +-- .../com/intuit/tank/harness/UserTracker.java | 2 +- .../intuit/tank/harness/APIMonitorTest.java | 6 +-- .../intuit/tank/harness/UserTrackerTest.java | 2 +- .../rest/mvc/rest/clients/AgentClient.java | 2 +- .../mvc/rest/controllers/AgentController.java | 2 +- .../mvc/rest/controllers/JobController.java | 2 +- .../rest/models/common/cloud/VMTracker.java | 6 +-- .../models/common/cloud/VMTrackerV2Impl.java | 8 ++-- .../rest/services/agent/AgentServiceV2.java | 2 +- .../services/agent/AgentServiceV2Impl.java | 2 +- .../mvc/rest/services/jobs/JobServiceV2.java | 2 +- .../rest/services/jobs/JobServiceV2Impl.java | 2 +- .../rest/mvc/rest/util/JobEventSender.java | 6 +-- .../rest/controllers/AgentControllerTest.java | 2 +- .../rest/controllers/JobControllerTest.java | 4 +- .../tank/service/util/MessageSender.java | 44 ------------------- .../tank/tools/debugger/PanelBuilder.java | 2 +- .../intuit/tank/ProjectDescriptionBean.java | 2 - 20 files changed, 32 insertions(+), 78 deletions(-) delete mode 100644 rest/service/common/src/main/java/com/intuit/tank/service/util/MessageSender.java diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java index 61c368da3..ac5adeaa2 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java @@ -19,9 +19,9 @@ import org.apache.logging.log4j.Logger; import com.intuit.tank.rest.mvc.rest.clients.AgentClient; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; -import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; -import com.intuit.tank.rest.mvc.rest.models.common.ValidationStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.VMStatus; +import com.intuit.tank.api.model.v1.cloud.ValidationStatus; import com.intuit.tank.harness.logging.LogUtil; import com.intuit.tank.reporting.api.TPSInfoContainer; import com.intuit.tank.vm.agent.messages.WatsAgentStatusResponse; diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java index c5131e5f3..e51e9195e 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java @@ -42,9 +42,9 @@ import org.apache.logging.log4j.message.ObjectMessage; import com.intuit.tank.rest.mvc.rest.clients.AgentClient; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; -import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; -import com.intuit.tank.rest.mvc.rest.models.common.ValidationStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.VMStatus; +import com.intuit.tank.api.model.v1.cloud.ValidationStatus; import com.intuit.tank.harness.data.HDTestPlan; import com.intuit.tank.harness.data.HDWorkload; import com.intuit.tank.harness.logging.LogUtil; diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java index b32c5abf0..625c237a1 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.stream.Collectors; -import com.intuit.tank.rest.mvc.rest.models.common.UserDetail; +import com.intuit.tank.api.model.v1.cloud.UserDetail; /** * diff --git a/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java b/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java index 215ed74a4..2817f2f4d 100644 --- a/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java +++ b/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java @@ -1,8 +1,8 @@ package com.intuit.tank.harness; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; -import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; -import com.intuit.tank.rest.mvc.rest.models.common.ValidationStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.VMStatus; +import com.intuit.tank.api.model.v1.cloud.ValidationStatus; import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.api.enumerated.VMImageType; import com.intuit.tank.vm.api.enumerated.VMRegion; diff --git a/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java b/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java index 635dd2f6e..802394c5d 100644 --- a/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java +++ b/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java @@ -18,7 +18,7 @@ import java.util.List; -import com.intuit.tank.rest.mvc.rest.models.common.UserDetail; +import com.intuit.tank.api.model.v1.cloud.UserDetail; import com.intuit.tank.test.TestGroups; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java index 8a33555ee..1a320e56d 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -9,7 +9,7 @@ import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentTestStartData; import com.intuit.tank.vm.agent.messages.AgentData; 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 b15f52ac5..0cc2d51e7 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 @@ -7,7 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; 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; 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 bc5e3d385..0f8e06ac7 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 @@ -7,7 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.services.jobs.JobServiceV2; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java index b2cced97d..7d69e69c8 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java @@ -7,9 +7,9 @@ */ package com.intuit.tank.rest.mvc.rest.models.common.cloud; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; -import com.intuit.tank.rest.mvc.rest.models.common.ProjectStatusContainer; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.api.model.v1.cloud.ProjectStatusContainer; import com.intuit.tank.vm.event.JobEvent; import javax.inject.Named; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java index 0a28dc9a8..42d46defe 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java @@ -9,10 +9,10 @@ import com.amazonaws.xray.AWSXRay; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; -import com.intuit.tank.rest.mvc.rest.models.common.ProjectStatusContainer; -import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.api.model.v1.cloud.ProjectStatusContainer; +import com.intuit.tank.api.model.v1.cloud.VMStatus; import com.intuit.tank.dao.JobInstanceDao; import com.intuit.tank.dao.WorkloadDao; import com.intuit.tank.project.JobInstance; 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 a2f2df39e..5284569af 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 @@ -8,7 +8,7 @@ package com.intuit.tank.rest.mvc.rest.services.agent; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; 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; 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 0cbaee1a3..8d8ec1816 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 @@ -13,7 +13,7 @@ import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.rest.mvc.rest.util.JobEventSender; import com.intuit.tank.rest.mvc.rest.util.ServletInjector; import com.intuit.tank.storage.FileData; 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 df4727566..5122fc4f3 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 @@ -9,7 +9,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.rest.mvc.rest.models.common.CloudVmStatusContainer; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; 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 d636c317e..39eb310d3 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 @@ -30,7 +30,7 @@ import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceInternalServerException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java index da3f12455..e19179e1a 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java @@ -15,9 +15,9 @@ import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.Workload; import com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTracker; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; -import com.intuit.tank.rest.mvc.rest.models.common.VMStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.api.model.v1.cloud.VMStatus; import com.intuit.tank.transform.scriptGenerator.ConverterUtil; import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; import com.intuit.tank.vm.api.enumerated.JobQueueStatus; diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java index c38f42105..a5cbdf52f 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java @@ -10,7 +10,7 @@ import com.intuit.tank.rest.mvc.rest.services.agent.AgentServiceV2; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentAvailabilityStatus; import com.intuit.tank.vm.agent.messages.AgentData; diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java index 96fa58e63..7288304e9 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java @@ -8,8 +8,8 @@ package com.intuit.tank.rest.mvc.rest.controllers; import com.intuit.tank.rest.mvc.rest.services.jobs.JobServiceV2; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatusContainer; -import com.intuit.tank.rest.mvc.rest.models.common.CloudVmStatus; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; diff --git a/rest/service/common/src/main/java/com/intuit/tank/service/util/MessageSender.java b/rest/service/common/src/main/java/com/intuit/tank/service/util/MessageSender.java deleted file mode 100644 index dcd4c7185..000000000 --- a/rest/service/common/src/main/java/com/intuit/tank/service/util/MessageSender.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank.service.util; - -/* - * #%L - * Automation Rest Service - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -import com.intuit.tank.vm.settings.ModifiedEntityMessage; - -import javax.annotation.Nonnull; -import javax.enterprise.event.Event; -import javax.inject.Inject; - -/** - * MessageSender - * - * @author dangleton - * - */ -public class MessageSender { - - @Inject - private Event eventSender; - - /** - * Fires the specified event - * - * @param msg - */ - public void sendEvent(@Nonnull ModifiedEntityMessage msg) { - eventSender.fire(msg); - } -} diff --git a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java index a06021fb0..e9284e5ab 100644 --- a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java +++ b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java @@ -53,7 +53,7 @@ public class PanelBuilder { private static File workingDir; - private static final String HEADERS_PATH = "/api/v2/agent/headers"; + private static final String HEADERS_PATH = "/v2/agent/headers"; private static final char NEWLINE = '\n'; public static File createWorkingDir(AgentDebuggerFrame frame, String baseUrl) { diff --git a/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java b/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java index d7d3c5653..57dc576f3 100644 --- a/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java @@ -68,8 +68,6 @@ public class ProjectDescriptionBean extends SelectableBean implements S public void init() { tablePrefs = new TablePreferences(userPrefs.getPreferences().getProjectTableColumns()); tablePrefs.registerListener(userPrefs); - messages.warn("Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + - "please download the newest version of Tank tools under the Tools tab. Refer to the API documentation under Help for more details."); } public void deleteSelectedProject() { From 6cdbd450486e674f6044239c6d04eb0e1074ce03 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Thu, 8 Jun 2023 15:57:44 -0700 Subject: [PATCH 27/73] updating vmtracker as well --- .../com/intuit/tank/agent/AgentStartup.java | 3 + pom.xml | 6 + .../mvc/rest/models/common/CloudVmStatus.java | 332 ---------------- .../models/common/CloudVmStatusContainer.java | 192 ---------- .../mvc/rest/models/common/Namespace.java | 16 - .../models/common/ProjectStatusContainer.java | 126 ------ .../mvc/rest/models/common/UserDetail.java | 80 ---- .../rest/mvc/rest/models/common/VMStatus.java | 34 -- .../rest/models/common/ValidationStatus.java | 210 ---------- .../rest/models/common/cloud/VMTracker.java | 102 ----- .../models/common/cloud/VMTrackerV2Impl.java | 358 ------------------ .../rest/mvc/rest/util/JobEventSender.java | 2 +- .../src/main/resources/META-INF/beans.xml | 3 - 13 files changed, 10 insertions(+), 1454 deletions(-) delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java delete mode 100644 rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java diff --git a/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java b/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java index 57bd73214..136fbdee5 100644 --- a/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java +++ b/agent/agent_startup/src/main/java/com/intuit/tank/agent/AgentStartup.java @@ -120,5 +120,8 @@ private static void usage() { System.out.println("Tank Test Startup Usage:"); System.out.println("java -cp agent-startup-pkg-1.0-all.jar com/intuit/tank/agent/AgentStartup "); System.out.println("-controller=: The url of the controller to get test info from"); + System.out.println("Service Path: " + SERVICE_RELATIVE_PATH); + System.out.println("Settings Method: " + METHOD_SETTINGS); + System.out.println("Support Files Method: " + METHOD_SUPPORT); } } diff --git a/pom.xml b/pom.xml index 71071ecf1..026bc5bd4 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ 2.7.6 5.3.25 2.7.6 + 2.20.0 3.10.1 @@ -856,6 +857,11 @@ ${version.spring-webflux} + + org.apache.logging.log4j + log4j-slf4j-impl + ${version.log4j} + diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java deleted file mode 100644 index d610fd7d9..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatus.java +++ /dev/null @@ -1,332 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common; - - -import com.intuit.tank.vm.api.enumerated.JobStatus; -import com.intuit.tank.vm.api.enumerated.VMImageType; -import com.intuit.tank.vm.api.enumerated.VMRegion; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.commons.lang3.builder.ToStringBuilder; - -import javax.xml.bind.annotation.*; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -@XmlRootElement(name = "cloudVm", namespace = Namespace.NAMESPACE_V1) -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CloudVm", namespace = Namespace.NAMESPACE_V1, propOrder = { - "instanceId", - "jobId", - "securityGroup", - "jobStatus", - "role", - "vmRegion", - "vmStatus", - "validationFailures", - "totalUsers", - "currentUsers", - "startTime", - "endTime", - "reportTime", - "totalTps", - "userDetails" -}) -public class CloudVmStatus implements Serializable { - - private static final long serialVersionUID = 1L; - - @XmlElement(name = "instanceId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private String instanceId; - - @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private String jobId; - - @XmlElement(name = "securityGroup", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private String securityGroup; - - @XmlElement(name = "jobStatus", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private JobStatus jobStatus = JobStatus.Unknown; - - @XmlElement(name = "role", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private VMImageType role = VMImageType.AGENT; - - @XmlElement(name = "vmRegion", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private VMRegion vmRegion; - - @XmlElement(name = "vmStatus", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private VMStatus vmStatus = VMStatus.unknown; - - @XmlElement(name = "validationFailures", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private ValidationStatus validationFailures; - - @XmlElement(name = "totalUsers", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private int totalUsers; - - @XmlElement(name = "currentUsers", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private int currentUsers; - - @XmlElement(name = "startTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) - private Date startTime; - - @XmlElement(name = "endTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) - private Date endTime; - - @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) - private Date reportTime; - - @XmlElement(name = "totalTps", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) - private int totalTps; - - @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) - @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private List userDetails = new ArrayList(); - - protected CloudVmStatus() { - } - - /** - * @param instanceId - * @param jobId - * @param securityGroup - * @param jobStatus - * @param vmStatus - * @param totalUsers - * @param currentUsers - */ - public CloudVmStatus(String instanceId, String jobId, String securityGroup, JobStatus jobStatus, VMImageType role, - VMRegion vmRegion, - VMStatus vmStatus, ValidationStatus validationFailures, - int totalUsers, int currentUsers, Date startTime, Date endTime) { - super(); - this.instanceId = instanceId; - this.jobId = jobId; - this.securityGroup = securityGroup; - this.vmRegion = vmRegion; - this.role = role; - this.jobStatus = jobStatus; - this.vmStatus = vmStatus; - this.validationFailures = validationFailures; - this.totalUsers = totalUsers; - this.currentUsers = currentUsers; - this.startTime = startTime; - this.endTime = endTime; - } - - /** - * - * @param copy - */ - public CloudVmStatus(CloudVmStatus copy) { - this.instanceId = copy.instanceId; - this.jobId = copy.jobId; - this.securityGroup = copy.securityGroup; - this.vmRegion = copy.vmRegion; - this.role = copy.role; - this.jobStatus = copy.jobStatus; - this.vmStatus = copy.vmStatus; - this.validationFailures = copy.validationFailures; - this.totalUsers = copy.totalUsers; - this.currentUsers = copy.currentUsers; - this.startTime = copy.startTime; - this.endTime = copy.endTime; - this.totalTps = copy.totalTps; - } - - /** - * @return the tpsInfo - */ - public int getTotalTps() { - return totalTps; - } - - /** - * @param totalTps - * the tpsInfo to set - */ - public void setTotalTps(int totalTps) { - this.totalTps = totalTps; - } - - /** - * @return the userDetails - */ - public List getUserDetails() { - return userDetails; - } - - /** - * @param userDetails - * the userDetails to set - */ - public void setUserDetails(List userDetails) { - this.userDetails = userDetails; - } - - /** - * @return the validationFailures - */ - public ValidationStatus getValidationFailures() { - return validationFailures; - } - - /** - * @return the instanceId - */ - public String getInstanceId() { - return instanceId; - } - - /** - * @return the vmRegion - */ - public VMRegion getVmRegion() { - return vmRegion; - } - - /** - * @return the jobId - */ - public String getJobId() { - return jobId; - } - - /** - * @return the securityGroup - */ - public String getSecurityGroup() { - return securityGroup; - } - - /** - * @return the jobStatus - */ - public JobStatus getJobStatus() { - return jobStatus; - } - - /** - * @return the vmStatus - */ - public VMStatus getVmStatus() { return vmStatus; } - - /** - * @return the totalUsers - */ - public int getTotalUsers() { - return totalUsers; - } - - /** - * @return the currentUsers - */ - public int getCurrentUsers() { - return currentUsers; - } - - /** - * @return the role - */ - public VMImageType getRole() { - return role; - } - - /** - * @return the startTime - */ - public Date getStartTime() { - return startTime; - } - - /** - * @return the endTime - */ - public Date getEndTime() { - return endTime; - } - - /** - * @return the reportTime - */ - public Date getReportTime() { - return reportTime; - } - - /** - * @param reportTime - * the reportTime to set - */ - public void setReportTime(Date reportTime) { - this.reportTime = reportTime; - } - - /** - * @param jobStatus - * the jobStatus to set - */ - public void setJobStatus(JobStatus jobStatus) { - this.jobStatus = jobStatus; - } - - /** - * @param vmStatus - * the vmStatus to set - */ - public void setVmStatus(VMStatus vmStatus) { - this.vmStatus = vmStatus; - } - - /** - * @param currentUsers - * the currentUsers to set - */ - public void setCurrentUsers(int currentUsers) { - this.currentUsers = currentUsers; - } - - /** - * @param endTime - * the endTime to set - */ - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(Object obj) { - if (!(obj instanceof CloudVmStatus)) { - return false; - } - CloudVmStatus o = (CloudVmStatus) obj; - return new EqualsBuilder().append(o.getInstanceId(), getInstanceId()).append(o.getJobId(), getJobId()) - .isEquals(); - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return new HashCodeBuilder(29, 45).append(getInstanceId()).append(getJobId()).toHashCode(); - } - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java deleted file mode 100644 index 428132fe3..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/CloudVmStatusContainer.java +++ /dev/null @@ -1,192 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common; - -import com.intuit.tank.vm.api.enumerated.JobQueueStatus; -import com.intuit.tank.vm.settings.TimeUtil; - -import javax.xml.bind.annotation.*; -import java.io.Serializable; -import java.util.*; -import java.util.stream.Collectors; - -@XmlRootElement(name = "cloudVmContainer", namespace = Namespace.NAMESPACE_V1) -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CloudVmStatusContainer", namespace = Namespace.NAMESPACE_V1, propOrder = { - "statuses", - "status", - "startTime", - "endTime", - "reportTime", - "jobId", - "userDetails" -}) -public class CloudVmStatusContainer implements Serializable, Comparable { - - private static final long serialVersionUID = 1L; - - @XmlElementWrapper(name = "statuses", namespace = Namespace.NAMESPACE_V1) - @XmlElement(name = "status", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private Set statuses = new HashSet(); - - @XmlElement(name = "status", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) - private JobQueueStatus status = JobQueueStatus.Created; - - @XmlElement(name = "startTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private Date startTime = new Date(); - - @XmlElement(name = "endTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) - private Date endTime; - - @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private Date reportTime = new Date(); - - @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) - private String jobId; - - @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) - @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private List userDetails = new ArrayList(); - - @XmlTransient - private Map> detailMap = new HashMap>(); - - /** - * @FrameworkUseOnly - */ - public CloudVmStatusContainer() { - } - - /** - * @param statuses - */ - public CloudVmStatusContainer(Set statuses) { - this.statuses = statuses; - } - - public JobQueueStatus getStatus() { - return status; - } - - public void setStatus(JobQueueStatus status) { - this.status = status; - } - - public void calculateUserDetails() { - List details; - Map map = new HashMap(); - for (CloudVmStatus status : statuses) { - for (UserDetail detail : status.getUserDetails()) { - Integer val = map.get(detail.getScript()); - if (val == null) { - val = 0; - } - map.put(detail.getScript(), val + detail.getUsers()); - } - } - details = map.entrySet().stream().map(entry -> new UserDetail(entry.getKey(), entry.getValue())).sorted().collect(Collectors.toList()); - userDetails = details; - detailMap.put(TimeUtil.normalizeToPeriod(15, new Date()), details); - } - - /** - * @return the detailMap - */ - public Map> getDetailMap() { - return detailMap; - } - - /** - * @return the statuses - */ - public Set getStatuses() { - return statuses; - } - - /** - * @return the startTime - */ - public Date getStartTime() { - return startTime; - } - - /** - * @param startTime - * the startTime to set - */ - public void setStartTime(Date startTime) { - this.startTime = startTime; - } - - /** - * @return the endTime - */ - public Date getEndTime() { - return endTime; - } - - /** - * @return the userDetails - */ - public List getUserDetails() { - return userDetails; - } - - /** - * @param endTime - * the endTime to set - */ - public void setEndTime(Date endTime) { - this.endTime = endTime; - } - - /** - * @return the reportTime - */ - public Date getReportTime() { - return reportTime; - } - - /** - * @param reportTime - * the reportTime to set - */ - public void setReportTime(Date reportTime) { - this.reportTime = reportTime; - } - - /** - * @return the jobId - */ - public String getJobId() { - return jobId; - } - - /** - * @param jobId - * the jobId to set - */ - public void setJobId(String jobId) { - this.jobId = jobId; - } - - /** - * {@inheritDoc} - */ - @Override - public int compareTo(CloudVmStatusContainer o) { - if (this.startTime != null) { - return this.startTime.compareTo(o.startTime); - } else if (o.startTime != null) { - return -1; - } - // both null - return 0; - } - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java deleted file mode 100644 index d5515be9f..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/Namespace.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common; - -public class Namespace { - - public static final String NAMESPACE_V1 = "urn:tank/domain/agent/v2"; - - private Namespace() { - } -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java deleted file mode 100644 index 2417e1f26..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ProjectStatusContainer.java +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common; - - -import com.intuit.tank.vm.settings.TimeUtil; - -import javax.xml.bind.annotation.*; -import java.io.Serializable; -import java.util.*; -import java.util.stream.Collectors; - -@XmlRootElement(name = "projectStatusContainer", namespace = Namespace.NAMESPACE_V1) -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "ProjectStatusContainer", namespace = Namespace.NAMESPACE_V1, propOrder = { - "reportTime", - "jobId", - "userDetails" -}) -public class ProjectStatusContainer implements Serializable { - - private static final long serialVersionUID = 1L; - - @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private Date reportTime = new Date(); - - @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) - private String jobId; - - @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) - @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private List userDetails = null; - - @XmlTransient - private Map> detailMap = new HashMap>(); - - @XmlTransient - private Map containers = new HashMap(); - - /** - * @FrameworkUseOnly - */ - public ProjectStatusContainer() { - } - - public void addStatusContainer(CloudVmStatusContainer container) { - containers.put(container.getJobId(), container); - calculateUserDetails(); - } - - public void calculateUserDetails() { - List details; - Map map = new HashMap(); - long oldTime = System.currentTimeMillis() - 120000;// 2 minutes - Set toRemove = new HashSet(); - for (CloudVmStatusContainer container : containers.values()) { - if (container.getReportTime().getTime() < oldTime) { - toRemove.add(container.getJobId()); - } else { - for (UserDetail detail : container.getUserDetails()) { - Integer val = map.get(detail.getScript()); - if (val == null) { - val = 0; - } - map.put(detail.getScript(), val + detail.getUsers()); - } - } - } - details = map.entrySet().stream().map(entry -> new UserDetail(entry.getKey(), entry.getValue())).sorted().collect(Collectors.toList()); - userDetails = details; - detailMap.put(TimeUtil.normalizeToPeriod(15, new Date()), details); - for (String s : toRemove) { - containers.remove(s); - } - } - - /** - * @return the detailMap - */ - public Map> getDetailMap() { - return detailMap; - } - - /** - * @return the userDetails - */ - public List getUserDetails() { - return userDetails; - } - - /** - * @return the reportTime - */ - public Date getReportTime() { - return reportTime; - } - - /** - * @param reportTime - * the reportTime to set - */ - public void setReportTime(Date reportTime) { - this.reportTime = reportTime; - } - - /** - * @return the jobId - */ - public String getJobId() { - return jobId; - } - - /** - * @param jobId - * the jobId to set - */ - public void setJobId(String jobId) { - this.jobId = jobId; - } - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java deleted file mode 100644 index d15f979a4..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/UserDetail.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common; - -import org.apache.commons.lang3.builder.ToStringBuilder; - -import javax.xml.bind.annotation.*; -import java.io.Serializable; -import java.util.Date; - -@XmlRootElement(name = "UserDetail", namespace = Namespace.NAMESPACE_V1) -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "UserDetail", namespace = Namespace.NAMESPACE_V1) -public class UserDetail implements Serializable, Comparable { - - private static final long serialVersionUID = 1L; - - @XmlElement(name = "script", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private String script; - - @XmlElement(name = "users", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private Integer users; - - @XmlElement(name = "created", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private Date createTime; - - /** - * @{frameworkUseOnly - */ - public UserDetail() { - - } - - public UserDetail(String script, Integer users) { - super(); - this.script = script; - this.users = users; - this.createTime = new Date(); - } - - /** - * @return the script - */ - public String getScript() { - return script; - } - - /** - * @return the users - */ - public Integer getUsers() { - return users; - } - - /** - * @return the createTime - */ - public Date getCreateTime() { - return createTime; - } - - @Override - public int compareTo(UserDetail o) { - return script.compareTo(o.script); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java deleted file mode 100644 index c520a7054..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/VMStatus.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common; - -import java.io.Serializable; - -public enum VMStatus implements Serializable { - unknown, - starting, - pending, - rampPaused, - rebooting, - running, - stopping, - stopped, - shutting_down, - terminated; - - public static final VMStatus fromString(String value) { - VMStatus ret = null; - if ("shutting-down".equals(value)) { - ret = VMStatus.shutting_down; - } else { - ret = VMStatus.valueOf(value); - } - return ret != null ? ret : VMStatus.unknown; - } - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java deleted file mode 100644 index 18365e7f2..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/ValidationStatus.java +++ /dev/null @@ -1,210 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common; - -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; -import org.apache.commons.lang3.builder.ToStringBuilder; - -import javax.xml.bind.annotation.*; -import java.io.Serializable; - -@XmlRootElement(name = "validationCloudVm", namespace = Namespace.NAMESPACE_V1) -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "validationCloudVm", namespace = Namespace.NAMESPACE_V1, propOrder = { - "kills", - "aborts", - "gotos", - "skips", - "skipGroups", - "restarts" -}) -public class ValidationStatus implements Serializable { - - private static final long serialVersionUID = 1L; - - @XmlElement(name = "kills", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private int kills; - - @XmlElement(name = "aborts", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private int aborts; - - @XmlElement(name = "gotos", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private int gotos; - - @XmlElement(name = "skips", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private int skips; - - @XmlElement(name = "skipGroups", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private int skipGroups; - - @XmlElement(name = "restarts", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) - private int restarts; - - public ValidationStatus() { - } - - /** - * - */ - public ValidationStatus(int kills, int aborts, int gotos, int skips, int skipGroups, int restarts) { - super(); - this.kills = kills; - this.aborts = aborts; - this.gotos = gotos; - this.skips = skips; - this.skipGroups = skipGroups; - this.restarts = restarts; - } - - /** - * @return total number of failures - */ - public int getTotal() { - return kills + aborts + gotos + skips + skipGroups + restarts; - } - - /** - * @return the validationKills - */ - public int getValidationKills() { - return kills; - } - - /** - * @return the validationAborts - */ - public int getValidationAborts() { - return aborts; - } - - /** - * @return the validationGotos - */ - public int getValidationGotos() { - return gotos; - } - - /** - * @return the validationSkips - */ - public int getValidationSkips() { - return skips; - } - - /** - * @return the validationSkipGroups - */ - public int getValidationSkipGroups() { - return skipGroups; - } - - /** - * @return the validationRestarts - */ - public int getValidationRestarts() { - return restarts; - } - - /** - * Add fail counts from another ValidationStatus - */ - public void addFailures(ValidationStatus other) { - this.kills += other.kills; - this.aborts += other.aborts; - this.gotos += other.gotos; - this.skips += other.skips; - this.skipGroups += other.skipGroups; - this.restarts += other.restarts; - } - - /** - * Update kill count - */ - public void addKill() { - kills++; - } - - /** - * Update abort count - */ - public void addAbort() { - aborts++; - } - - /** - * Update goto count - */ - public void addGoto() { - gotos++; - } - - /** - * Update skip count - */ - public void addSkip() { - skips++; - } - - /** - * Update skip group count - */ - public void addSkipGroup() { - skipGroups++; - } - - /** - * Update restart count - */ - public void addRestart() { - restarts++; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(Object obj) { - if (!(obj instanceof ValidationStatus)) { - return false; - } - ValidationStatus o = (ValidationStatus) obj; - return new EqualsBuilder() - .append(o.getValidationKills(), getValidationKills()) - .append(o.getValidationAborts(), getValidationAborts()) - .append(o.getValidationGotos(), getValidationGotos()) - .append(o.getValidationSkips(), getValidationSkips()) - .append(o.getValidationSkipGroups(), getValidationSkipGroups()) - .append(o.getValidationRestarts(), getValidationRestarts()) - .isEquals(); - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - return new HashCodeBuilder(29, 37) - .append(getValidationKills()) - .append(getValidationAborts()) - .append(getValidationGotos()) - .append(getValidationSkips()) - .append(getValidationSkipGroups()) - .append(getValidationRestarts()) - .toHashCode(); - } - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java deleted file mode 100644 index 7d69e69c8..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTracker.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common.cloud; - -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.ProjectStatusContainer; -import com.intuit.tank.vm.event.JobEvent; -import javax.inject.Named; - -import javax.annotation.Nonnull; -import java.util.Set; - -@Named -public interface VMTracker { - - /** - * - * @param projectId - * @return - */ - public ProjectStatusContainer getProjectStatusContainer(String projectId); - - /** - * - * @param event - * the event to publish - */ - public void publishEvent(JobEvent event); - - /** - * Gets the Status of the instance. - * - * @param instanceId - * the instance id to get the status for - * @return the status or null - */ - public CloudVmStatus getStatus(@Nonnull String instanceId); - - /** - * Sets the status of the specified instance. - * - * @param status - * the status to set to - */ - public void setStatus(@Nonnull CloudVmStatus status); - - /** - * @param jobId - * the id of the job to get the vmstatuses for. - * @return the container with all the statuses. - */ - public CloudVmStatusContainer getVmStatusForJob(String jobId); - - /** - * Tests if we are in dev mode for killing of instances sample data. - * - * @return - */ - public boolean isDevMode(); - - /** - * Remove the specified instance of a job. - * - * @param instanceId - * the instance of the jkob to remove - */ - public void removeStatusForInstance(String instanceId); - - /** - * Removes the Statuses for the specified job Id - * - * @param jobId - * the job to remove - */ - public void removeStatusForJob(String jobId); - - /** - * - * @return - */ - public Set getAllJobs(); - - /** - * @param id - * the job id - */ - public boolean isRunning(String id); - - /** - * - * @param id - * the job Id - */ - public void stopJob(String id); - -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java deleted file mode 100644 index 42d46defe..000000000 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/models/common/cloud/VMTrackerV2Impl.java +++ /dev/null @@ -1,358 +0,0 @@ -/** - * Copyright 2015-2023 Intuit Inc. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.intuit.tank.rest.mvc.rest.models.common.cloud; - - -import com.amazonaws.xray.AWSXRay; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.ProjectStatusContainer; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.dao.JobInstanceDao; -import com.intuit.tank.dao.WorkloadDao; -import com.intuit.tank.project.JobInstance; -import com.intuit.tank.project.Workload; -import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; -import com.intuit.tank.vm.api.enumerated.JobQueueStatus; -import com.intuit.tank.vm.api.enumerated.JobStatus; -import com.intuit.tank.vm.common.TankConstants; -import com.intuit.tank.vm.event.JobEvent; -import com.intuit.tank.vm.settings.TankConfig; -import com.intuit.tank.vmManager.environment.amazon.AmazonInstance; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nonnull; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.event.Event; -import javax.enterprise.inject.Instance; -import javax.enterprise.inject.Alternative; -import javax.inject.Inject; -import javax.inject.Named; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.*; - -import static com.intuit.tank.vm.common.TankConstants.NOTIFICATIONS_EVENT_EVENT_TIME_KEY; - -@Named -@ApplicationScoped -@Alternative -public class VMTrackerV2Impl implements VMTracker { - private static final Logger LOG = LogManager.getLogger(VMTrackerV2Impl.class); - - private ConcurrentMap locks = new ConcurrentHashMap(); - private boolean devMode = false; - - @Inject - private Event jobEventProducer; - - @Inject - private Instance jobInstanceDao; - - @Inject - private Instance workloadDaoInstance; - - private Map jobToProjectIdMap = new ConcurrentHashMap(); - private Map projectContainerMap = new ConcurrentHashMap(); - private Map statusMap = new ConcurrentHashMap(); - private Map jobMap = new ConcurrentHashMap(); - private Set stoppedJobs = new HashSet(); - - private static final ThreadPoolExecutor EXECUTOR = - new ThreadPoolExecutor(10, 50, 60, TimeUnit.SECONDS, - new ArrayBlockingQueue(50), - threadFactoryRunnable -> { - Thread t = Executors.defaultThreadFactory().newThread(threadFactoryRunnable); - t.setDaemon(true); - return t; - }, - new ThreadPoolExecutor.DiscardOldestPolicy()); - - /** - * - */ - @PostConstruct - public void init() { - devMode = new TankConfig().getStandalone(); - } - - /** - * {@inheritDoc} - */ - @Override - public CloudVmStatus getStatus(@Nonnull String instanceId) { - return statusMap.get(instanceId); - } - - public ProjectStatusContainer getProjectStatusContainer(String projectId) { - return projectContainerMap.get(projectId); - } - - /** - * {@inheritDoc} - */ - @Override - public void publishEvent(JobEvent event) { - try { - jobEventProducer.fire(event); - } catch (Exception e) { - LOG.error("Error firing Event: " + e, e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setStatus(@Nonnull final CloudVmStatus status) { - Runnable task = () -> setStatusThread(status); - AWSXRay.createSubsegment("Update.Status", task); //initiation call has already returned 204 - EXECUTOR.execute(task); - } - - private void setStatusThread(@Nonnull final CloudVmStatus status) { - synchronized (getCacheSyncObject(status.getJobId())) { - status.setReportTime(new Date()); - CloudVmStatus currentStatus = getStatus(status.getInstanceId()); - if (shouldUpdateStatus(currentStatus)) { - statusMap.put(status.getInstanceId(), status); - if (status.getVmStatus() == VMStatus.running - && (status.getJobStatus() == JobStatus.Completed) - && !isDevMode()) { - AmazonInstance amzInstance = new AmazonInstance(status.getVmRegion()); - amzInstance.killInstances(Collections.singletonList(status.getInstanceId())); - } - } - String jobId = status.getJobId(); - CloudVmStatusContainer cloudVmStatusContainer = jobMap.get(jobId); - if (cloudVmStatusContainer == null) { - cloudVmStatusContainer = new CloudVmStatusContainer(); - cloudVmStatusContainer.setJobId(jobId); - - jobMap.put(jobId, cloudVmStatusContainer); - JobInstance job = jobInstanceDao.get().findById(Integer.parseInt(jobId)); - if (job != null) { - JobQueueStatus newStatus = getQueueStatus(job.getStatus(), status.getJobStatus()); - cloudVmStatusContainer.setStatus(newStatus); - if (newStatus != job.getStatus()) { - job.setStatus(newStatus); - new JobInstanceDao().saveOrUpdate(job); - } - } else { - JobQueueStatus newStatus = getQueueStatus(cloudVmStatusContainer.getStatus(), status.getJobStatus()); - cloudVmStatusContainer.setStatus(newStatus); - } - } - cloudVmStatusContainer.setReportTime(status.getReportTime()); - addStatusToJobContainer(status, cloudVmStatusContainer); - String projectId = getProjectForJobId(jobId); - if (projectId != null) { - ProjectStatusContainer projectStatusContainer = getProjectStatusContainer(projectId); - if (projectStatusContainer == null) { - projectStatusContainer = new ProjectStatusContainer(); - projectContainerMap.put(projectId, projectStatusContainer); - } - projectStatusContainer.addStatusContainer(cloudVmStatusContainer); - } - } - } - - private String getProjectForJobId(String jobId) { - String ret = jobToProjectIdMap.get(jobId); - if (ret == null) { - try { - JobInstance jobInstance = jobInstanceDao.get().findById(Integer.valueOf(jobId)); - Workload wkld = workloadDaoInstance.get().findById(jobInstance.getWorkloadId()); - ret = Integer.toString(wkld.getProject().getId()); - } catch (Exception e) { - LOG.error("cannot get projectId for jobId " + jobId + ": " + e.toString(), e); - ret = ""; - } - jobToProjectIdMap.put(jobId, ret); - } - return StringUtils.isNotBlank(ret) ? ret : null; - } - - /** - * @param oldStatus - * @param jobStatus - * @return - */ - private JobQueueStatus getQueueStatus(JobQueueStatus oldStatus, JobStatus jobStatus) { - try { - return JobQueueStatus.valueOf(jobStatus.name()); - } catch (Exception e) { - LOG.error("Error converting status from " + jobStatus); - } - return oldStatus; - } - - /** - * If the vm is shutting down or terminated, don't update the status to something else. - * @param currentStatus - * @return - */ - private boolean shouldUpdateStatus(CloudVmStatus currentStatus) { - if (currentStatus != null) { - VMStatus status = currentStatus.getVmStatus(); - return (status != VMStatus.shutting_down - && status != VMStatus.stopped - && status != VMStatus.stopping - && status != VMStatus.terminated); - } - return true; - } - - /** - * - * {@inheritDoc} - */ - @Override - public void removeStatusForInstance(String instanceId) { - statusMap.remove(instanceId); - } - - /** - * - * {@inheritDoc} - */ - @Override - public void removeStatusForJob(String jobId) { - CloudVmStatusContainer cloudVmStatusContainer = jobMap.get(jobId); - if (cloudVmStatusContainer != null) { - for (CloudVmStatus s : cloudVmStatusContainer.getStatuses()) { - removeStatusForInstance(s.getInstanceId()); - } - jobMap.remove(jobId); - } - } - - /** - * {@inheritDoc} - */ - @Override - public CloudVmStatusContainer getVmStatusForJob(String jobId) { - return jobMap.get(jobId); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isDevMode() { - return devMode; - } - - /** - * {@inheritDoc} - */ - @Override - public Set getAllJobs() { - return new HashSet(jobMap.values()); - } - - @Override - public boolean isRunning(String id) { - return !stoppedJobs.contains(id); - } - - @Override - public void stopJob(String id) { - stoppedJobs.add(id); - } - - /** - * @param status - * @param cloudVmStatusContainer - **/ - private void addStatusToJobContainer(CloudVmStatus status, CloudVmStatusContainer cloudVmStatusContainer) { - cloudVmStatusContainer.getStatuses().remove(status); - cloudVmStatusContainer.getStatuses().add(status); - cloudVmStatusContainer.calculateUserDetails(); - boolean isFinished = true; - boolean paused = true; - boolean rampPaused = true; - boolean stopped = true; - boolean running = true; - - // look up the job - JobInstance job = jobInstanceDao.get().findById(Integer.parseInt(status.getJobId())); - for (CloudVmStatus s : cloudVmStatusContainer.getStatuses()) { - JobStatus jobStatus = s.getJobStatus(); - if (jobStatus != JobStatus.Completed) { // If no VMs are Completed - isFinished = false; - } - if (jobStatus != JobStatus.Paused) { // If no VMs are Paused - paused = false; - } - if (jobStatus != JobStatus.RampPaused) { // If no VMs are RampPaused - rampPaused = false; - } - if (jobStatus != JobStatus.Stopped) { // If no VMs are Stopped - stopped = false; - } - if (jobStatus != JobStatus.Running) { // If no VMs are Running - running = false; - } - } - if (isFinished) { - LOG.info("Setting end time on container " + cloudVmStatusContainer.getJobId()); - if (cloudVmStatusContainer.getEndTime() == null) { - jobEventProducer.fire(new JobEvent(status.getJobId(), "", JobLifecycleEvent.JOB_FINISHED) - .addContextEntry(NOTIFICATIONS_EVENT_EVENT_TIME_KEY, - new SimpleDateFormat(TankConstants.DATE_FORMAT_WITH_TIMEZONE).format(new Date()))); - } - cloudVmStatusContainer.setEndTime(new Date()); - } - if (job != null) { - job.setEndTime(cloudVmStatusContainer.getEndTime()); - JobQueueStatus newStatus = job.getStatus(); - if (isFinished) { - newStatus = JobQueueStatus.Completed; - stopJob(Integer.toString(job.getId())); - } else if (paused) { - newStatus = JobQueueStatus.Paused; - } else if (rampPaused) { - newStatus = JobQueueStatus.RampPaused; - } else if (stopped) { - newStatus = JobQueueStatus.Stopped; - } else if (running) { - newStatus = JobQueueStatus.Running; - if (job.getStartTime() == null && status.getJobStatus() == JobStatus.Running) { - job.setStartTime(status.getStartTime()); - jobEventProducer.fire(new JobEvent(Integer.toString(job.getId()), "", JobLifecycleEvent.LOAD_STARTED)); - } - } - - LOG.trace("Setting Container for job=" + status.getJobId() + " newStatus to " + newStatus); - job.setStatus(newStatus); - jobInstanceDao.get().saveOrUpdate(job); - - // Job StartTime is source of truth for cloudVMStatusContainer StartTime - if (job.getStartTime() != null && cloudVmStatusContainer.getStartTime() != null) { - if (job.getStartTime().before(cloudVmStatusContainer.getStartTime())) { - cloudVmStatusContainer.setStartTime(job.getStartTime()); - } - } - } - } - - private Object getCacheSyncObject(final String id) { - locks.putIfAbsent(id, id); - return locks.get(id); - } - - @PreDestroy - private void destroy() { - EXECUTOR.shutdown(); - } -} diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java index e19179e1a..7c0ce5be4 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java @@ -14,7 +14,7 @@ import com.intuit.tank.perfManager.workLoads.JobManager; import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.Workload; -import com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTracker; +import com.intuit.tank.api.cloud.VMTracker; import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; import com.intuit.tank.api.model.v1.cloud.VMStatus; diff --git a/rest-mvc/src/main/resources/META-INF/beans.xml b/rest-mvc/src/main/resources/META-INF/beans.xml index dd8f35fb2..8f3d7ba02 100644 --- a/rest-mvc/src/main/resources/META-INF/beans.xml +++ b/rest-mvc/src/main/resources/META-INF/beans.xml @@ -3,8 +3,5 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" bean-discovery-mode="all"> - - com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTrackerV2Impl - From c3d5b4db21e73aa117e83c64af3cb22cbb95c03b Mon Sep 17 00:00:00 2001 From: zkofiro Date: Thu, 8 Jun 2023 16:07:12 -0700 Subject: [PATCH 28/73] TankAPI fix --- .../main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java index 08bd0e8ac..588b2bba3 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java @@ -7,7 +7,6 @@ */ package com.intuit.tank.rest.mvc; -import com.intuit.tank.rest.mvc.rest.models.common.cloud.VMTrackerV2Impl; import com.intuit.tank.rest.mvc.rest.util.JobEventListener; import com.intuit.tank.rest.mvc.rest.util.JobEventSender; import io.swagger.v3.oas.annotations.OpenAPIDefinition; @@ -23,7 +22,7 @@ @OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server URL")}) @SpringBootApplication(proxyBeanMethods = false) @ComponentScan(basePackages = "com.intuit.tank.rest.mvc", excludeFilters = { - @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JobEventSender.class, JobEventListener.class, VMTrackerV2Impl.class}) + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JobEventSender.class, JobEventListener.class}) }) public class TankAPIApplication extends SpringBootServletInitializer { public static ConfigurableApplicationContext run(String[] args) { From c0531a074ef388e9b7b9c308d9f5cc0f0b299d8f Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 00:09:22 -0700 Subject: [PATCH 29/73] moving vmmanger + models outside of rest api --- .../com/intuit/tank/harness/APIMonitor.java | 6 +- .../intuit/tank/harness/APITestHarness.java | 6 +- .../com/intuit/tank/harness/UserTracker.java | 2 +- .../intuit/tank/harness/APIMonitorTest.java | 6 +- .../intuit/tank/harness/UserTrackerTest.java | 2 +- .../intuit/tank/vm/vmManager}/VMTracker.java | 8 +- .../vm/vmManager/models}/CloudVmStatus.java | 2 +- .../models}/CloudVmStatusContainer.java | 2 +- .../tank/vm/vmManager/models}/Namespace.java | 2 +- .../models}/ProjectStatusContainer.java | 2 +- .../tank/vm/vmManager/models}/UserDetail.java | 2 +- .../tank/vm/vmManager/models}/VMStatus.java | 2 +- .../vmManager/models}/ValidationStatus.java | 2 +- .../models}/CloudVmStatusContainerTest.java | 6 +- .../vmManager/models}/CloudVmStatusTest.java | 2 +- .../vm/vmManager/models}/NamespaceTest.java | 8 +- .../models}/ProjectStatusContainerTest.java | 7 +- .../vm/vmManager/models}/UserDetailTest.java | 5 +- .../vm/vmManager/models}/VMStatusTest.java | 8 +- .../models}/ValidationStatusTest.java | 4 +- .../rest/mvc/rest/clients/AgentClient.java | 2 +- .../{util => cloud}/JobEventListener.java | 2 +- .../rest/{util => cloud}/JobEventSender.java | 10 +- .../{util => cloud}/MessageEventSender.java | 2 +- .../rest/{util => cloud}/ServletInjector.java | 2 +- .../mvc/rest/controllers/AgentController.java | 2 +- .../mvc/rest/controllers/JobController.java | 2 +- .../rest/services/agent/AgentServiceV2.java | 2 +- .../services/agent/AgentServiceV2Impl.java | 6 +- .../services/filters/FilterServiceV2Impl.java | 4 +- .../mvc/rest/services/jobs/JobServiceV2.java | 2 +- .../rest/services/jobs/JobServiceV2Impl.java | 6 +- .../projects/ProjectServiceV2Impl.java | 4 +- .../services/scripts/ScriptServiceV2Impl.java | 4 +- .../rest/controllers/AgentControllerTest.java | 2 +- .../rest/controllers/JobControllerTest.java | 4 +- rest/api/cloud/.gitignore | 2 - rest/api/cloud/pom.xml | 25 - .../api/service/v1/cloud/CloudService.java | 358 -------------- .../src/main/resources/META-INF/beans.xml | 22 - .../intuit/tank/api/model/v1/cloud/jaxb.index | 5 - rest/api/pom.xml | 1 - rest/client/cloud/.gitignore | 1 - rest/client/cloud/pom.xml | 39 -- .../com/intuit/tank/CloudServiceClient.java | 339 -------------- .../src/main/resources/META-INF/beans.xml | 22 - rest/client/pom.xml | 1 - rest/service/cloud/.gitignore | 1 - rest/service/cloud/pom.xml | 58 --- .../impl/v1/cloud/CloudController.java | 141 ------ .../service/impl/v1/cloud/CloudServiceV1.java | 440 ------------------ .../service/impl/v1/cloud/CostingCache.java | 102 ---- .../service/impl/v1/cloud/JobController.java | 336 ------------- .../service/impl/v1/cloud/JobListener.java | 56 --- .../src/main/resources/META-INF/beans.xml | 22 - .../impl/v1/cloud/CloudSercieV1Test.java | 58 --- rest/service/pom.xml | 1 - rest/service/reporting/pom.xml | 7 - tank_vmManager/pom.xml | 6 - .../perfManager/workLoads/JobManager.java | 8 +- .../intuit/tank/vmManager/AgentWatchdog.java | 10 +- .../tank/vmManager/CloudWatchObserver.java | 6 +- .../tank/vmManager/VMTerminatorImpl.java | 2 +- .../intuit/tank/vmManager/VMTrackerImpl.java | 10 +- .../vmManager/VmMessageProcessorImpl.java | 8 +- .../vmManager/environment/CreateInstance.java | 10 +- .../vmManager/environment/JobRequest.java | 10 +- .../tank/vmManager/AgentWatchdogTest.java | 10 +- .../intuit/tank/ProjectDescriptionBean.java | 3 + .../java/com/intuit/tank/agent/AgentBean.java | 6 +- .../com/intuit/tank/job/ActJobNodeBean.java | 4 +- .../java/com/intuit/tank/job/JobNodeBean.java | 4 +- .../com/intuit/tank/job/JobQueueAction.java | 4 +- .../com/intuit/tank/job/JobStatusHelper.java | 2 +- .../com/intuit/tank/job/ProjectNodeBean.java | 2 +- .../java/com/intuit/tank/job/VMNodeBean.java | 2 +- .../NotificationContextBuilder.java | 8 +- .../tank/notification/NotificationRunner.java | 2 +- .../tank/notification/NotificationSender.java | 2 +- .../intuit/tank/project/JobTreeTableBean.java | 12 +- .../intuit/tank/job/ActJobNodeBeanTest.java | 8 +- .../com/intuit/tank/job/JobNodeBeanTest.java | 7 +- .../com/intuit/tank/job/VMNodeBeanTest.java | 9 +- .../notification/NotificationRunnerTest.java | 3 +- .../tank/project/JobTreeTableBeanTest.java | 2 +- .../src/main/webapp/projects/index.xhtml | 2 +- 86 files changed, 131 insertions(+), 2208 deletions(-) rename {rest/api/cloud/src/main/java/com/intuit/tank/api/cloud => api/src/main/java/com/intuit/tank/vm/vmManager}/VMTracker.java (91%) rename {rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud => api/src/main/java/com/intuit/tank/vm/vmManager/models}/CloudVmStatus.java (99%) rename {rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud => api/src/main/java/com/intuit/tank/vm/vmManager/models}/CloudVmStatusContainer.java (99%) rename {rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud => api/src/main/java/com/intuit/tank/vm/vmManager/models}/Namespace.java (92%) rename {rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud => api/src/main/java/com/intuit/tank/vm/vmManager/models}/ProjectStatusContainer.java (98%) rename {rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud => api/src/main/java/com/intuit/tank/vm/vmManager/models}/UserDetail.java (98%) rename {rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud => api/src/main/java/com/intuit/tank/vm/vmManager/models}/VMStatus.java (95%) rename {rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud => api/src/main/java/com/intuit/tank/vm/vmManager/models}/ValidationStatus.java (99%) rename {rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud => api/src/test/java/com/intuit/tank/vm/vmManager/models}/CloudVmStatusContainerTest.java (98%) rename {rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud => api/src/test/java/com/intuit/tank/vm/vmManager/models}/CloudVmStatusTest.java (99%) rename {rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud => api/src/test/java/com/intuit/tank/vm/vmManager/models}/NamespaceTest.java (74%) rename {rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud => api/src/test/java/com/intuit/tank/vm/vmManager/models}/ProjectStatusContainerTest.java (97%) rename {rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud => api/src/test/java/com/intuit/tank/vm/vmManager/models}/UserDetailTest.java (96%) rename {rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud => api/src/test/java/com/intuit/tank/vm/vmManager/models}/VMStatusTest.java (86%) rename {rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud => api/src/test/java/com/intuit/tank/vm/vmManager/models}/ValidationStatusTest.java (98%) rename rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/{util => cloud}/JobEventListener.java (96%) rename rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/{util => cloud}/JobEventSender.java (97%) rename rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/{util => cloud}/MessageEventSender.java (94%) rename rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/{util => cloud}/ServletInjector.java (96%) delete mode 100644 rest/api/cloud/.gitignore delete mode 100644 rest/api/cloud/pom.xml delete mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/service/v1/cloud/CloudService.java delete mode 100644 rest/api/cloud/src/main/resources/META-INF/beans.xml delete mode 100644 rest/api/cloud/src/main/resources/com/intuit/tank/api/model/v1/cloud/jaxb.index delete mode 100644 rest/client/cloud/.gitignore delete mode 100644 rest/client/cloud/pom.xml delete mode 100644 rest/client/cloud/src/main/java/com/intuit/tank/CloudServiceClient.java delete mode 100644 rest/client/cloud/src/main/resources/META-INF/beans.xml delete mode 100644 rest/service/cloud/.gitignore delete mode 100644 rest/service/cloud/pom.xml delete mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudController.java delete mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudServiceV1.java delete mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CostingCache.java delete mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobController.java delete mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobListener.java delete mode 100644 rest/service/cloud/src/main/resources/META-INF/beans.xml delete mode 100644 rest/service/cloud/src/test/java/com/intuit/tank/service/impl/v1/cloud/CloudSercieV1Test.java diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java index ac5adeaa2..c5fd046e3 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APIMonitor.java @@ -19,9 +19,9 @@ import org.apache.logging.log4j.Logger; import com.intuit.tank.rest.mvc.rest.clients.AgentClient; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.harness.logging.LogUtil; import com.intuit.tank.reporting.api.TPSInfoContainer; import com.intuit.tank.vm.agent.messages.WatsAgentStatusResponse; diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java index e51e9195e..492fb42af 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/APITestHarness.java @@ -42,9 +42,9 @@ import org.apache.logging.log4j.message.ObjectMessage; import com.intuit.tank.rest.mvc.rest.clients.AgentClient; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.harness.data.HDTestPlan; import com.intuit.tank.harness.data.HDWorkload; import com.intuit.tank.harness.logging.LogUtil; diff --git a/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java b/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java index 625c237a1..c8086514d 100644 --- a/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java +++ b/agent/apiharness/src/main/java/com/intuit/tank/harness/UserTracker.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.stream.Collectors; -import com.intuit.tank.api.model.v1.cloud.UserDetail; +import com.intuit.tank.vm.vmManager.models.UserDetail; /** * diff --git a/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java b/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java index 2817f2f4d..eddcab6ca 100644 --- a/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java +++ b/agent/apiharness/src/test/java/com/intuit/tank/harness/APIMonitorTest.java @@ -1,8 +1,8 @@ package com.intuit.tank.harness; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.api.enumerated.VMImageType; import com.intuit.tank.vm.api.enumerated.VMRegion; diff --git a/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java b/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java index 802394c5d..87662600b 100644 --- a/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java +++ b/agent/apiharness/src/test/java/com/intuit/tank/harness/UserTrackerTest.java @@ -18,7 +18,7 @@ import java.util.List; -import com.intuit.tank.api.model.v1.cloud.UserDetail; +import com.intuit.tank.vm.vmManager.models.UserDetail; import com.intuit.tank.test.TestGroups; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/cloud/VMTracker.java b/api/src/main/java/com/intuit/tank/vm/vmManager/VMTracker.java similarity index 91% rename from rest/api/cloud/src/main/java/com/intuit/tank/api/cloud/VMTracker.java rename to api/src/main/java/com/intuit/tank/vm/vmManager/VMTracker.java index 74f09088f..562668356 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/cloud/VMTracker.java +++ b/api/src/main/java/com/intuit/tank/vm/vmManager/VMTracker.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.api.cloud; +package com.intuit.tank.vm.vmManager; /* * #%L @@ -20,9 +20,9 @@ import javax.annotation.Nonnull; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.ProjectStatusContainer; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.ProjectStatusContainer; import com.intuit.tank.vm.event.JobEvent; /** diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java b/api/src/main/java/com/intuit/tank/vm/vmManager/models/CloudVmStatus.java similarity index 99% rename from rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java rename to api/src/main/java/com/intuit/tank/vm/vmManager/models/CloudVmStatus.java index 0433d57d9..f8ff1deb7 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java +++ b/api/src/main/java/com/intuit/tank/vm/vmManager/models/CloudVmStatus.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java b/api/src/main/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusContainer.java similarity index 99% rename from rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java rename to api/src/main/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusContainer.java index 8fc265b64..adee83973 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java +++ b/api/src/main/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusContainer.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java b/api/src/main/java/com/intuit/tank/vm/vmManager/models/Namespace.java similarity index 92% rename from rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java rename to api/src/main/java/com/intuit/tank/vm/vmManager/models/Namespace.java index 6a3d5bec6..2d0bc30a5 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java +++ b/api/src/main/java/com/intuit/tank/vm/vmManager/models/Namespace.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java b/api/src/main/java/com/intuit/tank/vm/vmManager/models/ProjectStatusContainer.java similarity index 98% rename from rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java rename to api/src/main/java/com/intuit/tank/vm/vmManager/models/ProjectStatusContainer.java index 478c722aa..df2f75899 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java +++ b/api/src/main/java/com/intuit/tank/vm/vmManager/models/ProjectStatusContainer.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java b/api/src/main/java/com/intuit/tank/vm/vmManager/models/UserDetail.java similarity index 98% rename from rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java rename to api/src/main/java/com/intuit/tank/vm/vmManager/models/UserDetail.java index 257f1c746..3704c0a3c 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java +++ b/api/src/main/java/com/intuit/tank/vm/vmManager/models/UserDetail.java @@ -1,4 +1,4 @@ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java b/api/src/main/java/com/intuit/tank/vm/vmManager/models/VMStatus.java similarity index 95% rename from rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java rename to api/src/main/java/com/intuit/tank/vm/vmManager/models/VMStatus.java index 298b51980..6c709b854 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java +++ b/api/src/main/java/com/intuit/tank/vm/vmManager/models/VMStatus.java @@ -1,4 +1,4 @@ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java b/api/src/main/java/com/intuit/tank/vm/vmManager/models/ValidationStatus.java similarity index 99% rename from rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java rename to api/src/main/java/com/intuit/tank/vm/vmManager/models/ValidationStatus.java index 908497141..395c6eeeb 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java +++ b/api/src/main/java/com/intuit/tank/vm/vmManager/models/ValidationStatus.java @@ -1,7 +1,7 @@ /** * Copyright 2013 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L diff --git a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainerTest.java b/api/src/test/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusContainerTest.java similarity index 98% rename from rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainerTest.java rename to api/src/test/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusContainerTest.java index 8b6b1211d..c99b015aa 100644 --- a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainerTest.java +++ b/api/src/test/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusContainerTest.java @@ -1,4 +1,4 @@ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L @@ -13,7 +13,6 @@ * #L% */ -import java.text.DateFormat; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -24,9 +23,6 @@ import static org.junit.jupiter.api.Assertions.*; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.UserDetail; import com.intuit.tank.vm.api.enumerated.JobQueueStatus; /** diff --git a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusTest.java b/api/src/test/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusTest.java similarity index 99% rename from rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusTest.java rename to api/src/test/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusTest.java index e1a092a72..b13284a9d 100644 --- a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusTest.java +++ b/api/src/test/java/com/intuit/tank/vm/vmManager/models/CloudVmStatusTest.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L diff --git a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/NamespaceTest.java b/api/src/test/java/com/intuit/tank/vm/vmManager/models/NamespaceTest.java similarity index 74% rename from rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/NamespaceTest.java rename to api/src/test/java/com/intuit/tank/vm/vmManager/models/NamespaceTest.java index de619c775..dad2ed682 100644 --- a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/NamespaceTest.java +++ b/api/src/test/java/com/intuit/tank/vm/vmManager/models/NamespaceTest.java @@ -1,4 +1,4 @@ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L @@ -13,12 +13,6 @@ * #L% */ -import org.junit.jupiter.api.*; - -import com.intuit.tank.api.model.v1.cloud.Namespace; - -import static org.junit.jupiter.api.Assertions.*; - /** * The class NamespaceTest contains tests for the class {@link Namespace}. * diff --git a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainerTest.java b/api/src/test/java/com/intuit/tank/vm/vmManager/models/ProjectStatusContainerTest.java similarity index 97% rename from rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainerTest.java rename to api/src/test/java/com/intuit/tank/vm/vmManager/models/ProjectStatusContainerTest.java index 60b0dbc36..469d9ca8c 100644 --- a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainerTest.java +++ b/api/src/test/java/com/intuit/tank/vm/vmManager/models/ProjectStatusContainerTest.java @@ -1,4 +1,4 @@ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L @@ -13,17 +13,12 @@ * #L% */ -import java.text.DateFormat; import java.util.Date; import java.util.List; import java.util.Map; import org.junit.jupiter.api.*; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.ProjectStatusContainer; -import com.intuit.tank.api.model.v1.cloud.UserDetail; - import static org.junit.jupiter.api.Assertions.*; /** diff --git a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/UserDetailTest.java b/api/src/test/java/com/intuit/tank/vm/vmManager/models/UserDetailTest.java similarity index 96% rename from rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/UserDetailTest.java rename to api/src/test/java/com/intuit/tank/vm/vmManager/models/UserDetailTest.java index 641d85b70..6051dbe0a 100644 --- a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/UserDetailTest.java +++ b/api/src/test/java/com/intuit/tank/vm/vmManager/models/UserDetailTest.java @@ -1,4 +1,4 @@ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L @@ -13,13 +13,10 @@ * #L% */ -import java.text.DateFormat; import java.util.Date; import org.junit.jupiter.api.*; -import com.intuit.tank.api.model.v1.cloud.UserDetail; - import static org.junit.jupiter.api.Assertions.*; /** diff --git a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/VMStatusTest.java b/api/src/test/java/com/intuit/tank/vm/vmManager/models/VMStatusTest.java similarity index 86% rename from rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/VMStatusTest.java rename to api/src/test/java/com/intuit/tank/vm/vmManager/models/VMStatusTest.java index 35846c1b5..117793759 100644 --- a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/VMStatusTest.java +++ b/api/src/test/java/com/intuit/tank/vm/vmManager/models/VMStatusTest.java @@ -1,4 +1,4 @@ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L @@ -59,10 +59,10 @@ public void testFromString_2() VMStatus result = VMStatus.fromString(value); // An unexpected exception was thrown in user code while executing this test: - // java.lang.IllegalArgumentException: No enum constant com.intuit.tank.api.model.v1.cloud.VMStatus. + // java.lang.IllegalArgumentException: No enum constant com.intuit.tank.vm.vmManager.models.VMStatus. // at java.lang.Enum.valueOf(Enum.java:238) - // at com.intuit.tank.api.model.v1.cloud.VMStatus.valueOf(VMStatus.java:5) - // at com.intuit.tank.api.model.v1.cloud.VMStatus.fromString(VMStatus.java:20) + // at com.intuit.tank.vm.vmManager.models.VMStatus.valueOf(VMStatus.java:5) + // at com.intuit.tank.vm.vmManager.models.VMStatus.fromString(VMStatus.java:20) assertNotNull(result); } } \ No newline at end of file diff --git a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/ValidationStatusTest.java b/api/src/test/java/com/intuit/tank/vm/vmManager/models/ValidationStatusTest.java similarity index 98% rename from rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/ValidationStatusTest.java rename to api/src/test/java/com/intuit/tank/vm/vmManager/models/ValidationStatusTest.java index 6b42f5d5a..7c85889b6 100644 --- a/rest/api/cloud/src/test/java/com/intuit/tank/api/model/v1/cloud/ValidationStatusTest.java +++ b/api/src/test/java/com/intuit/tank/vm/vmManager/models/ValidationStatusTest.java @@ -1,4 +1,4 @@ -package com.intuit.tank.api.model.v1.cloud; +package com.intuit.tank.vm.vmManager.models; /* * #%L @@ -15,8 +15,6 @@ import org.junit.jupiter.api.*; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; - import static org.junit.jupiter.api.Assertions.*; /** diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java index 1a320e56d..d2f9173c8 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/AgentClient.java @@ -9,7 +9,7 @@ import com.intuit.tank.rest.mvc.rest.clients.util.ClientException; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentTestStartData; import com.intuit.tank.vm.agent.messages.AgentData; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/JobEventListener.java similarity index 96% rename from rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java rename to rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/JobEventListener.java index 8db1beb6b..17925c050 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventListener.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/JobEventListener.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package com.intuit.tank.rest.mvc.rest.util; +package com.intuit.tank.rest.mvc.rest.cloud; import java.io.Serializable; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/JobEventSender.java similarity index 97% rename from rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java rename to rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/JobEventSender.java index 7c0ce5be4..321ec6b72 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/JobEventSender.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/JobEventSender.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package com.intuit.tank.rest.mvc.rest.util; +package com.intuit.tank.rest.mvc.rest.cloud; import com.intuit.tank.dao.JobInstanceDao; import com.intuit.tank.dao.WorkloadDao; @@ -14,10 +14,9 @@ import com.intuit.tank.perfManager.workLoads.JobManager; import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.Workload; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.VMStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.VMStatus; import com.intuit.tank.transform.scriptGenerator.ConverterUtil; import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; import com.intuit.tank.vm.api.enumerated.JobQueueStatus; @@ -27,6 +26,7 @@ import com.intuit.tank.vm.perfManager.AgentChannel; import com.intuit.tank.vm.settings.TankConfig; import com.intuit.tank.vm.vmManager.VMTerminator; +import com.intuit.tank.vm.vmManager.VMTracker; import com.intuit.tank.vmManager.environment.amazon.AmazonInstance; import com.amazonaws.xray.AWSXRay; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/MessageEventSender.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/MessageEventSender.java similarity index 94% rename from rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/MessageEventSender.java rename to rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/MessageEventSender.java index 2ed6156ad..c7beb7afe 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/MessageEventSender.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/MessageEventSender.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package com.intuit.tank.rest.mvc.rest.util; +package com.intuit.tank.rest.mvc.rest.cloud; import com.intuit.tank.vm.settings.ModifiedEntityMessage; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/ServletInjector.java similarity index 96% rename from rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java rename to rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/ServletInjector.java index 0d72083c4..89fd57cb8 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/util/ServletInjector.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/cloud/ServletInjector.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package com.intuit.tank.rest.mvc.rest.util; +package com.intuit.tank.rest.mvc.rest.cloud; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.spi.Bean; 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 0cc2d51e7..9b0d86c11 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 @@ -7,7 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; 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; 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 0f8e06ac7..48d7f51b6 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 @@ -7,7 +7,7 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.services.jobs.JobServiceV2; 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 5284569af..40162442a 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 @@ -8,7 +8,7 @@ package com.intuit.tank.rest.mvc.rest.services.agent; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; 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; 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 8d8ec1816..5146df007 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 @@ -13,9 +13,9 @@ import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.rest.mvc.rest.util.JobEventSender; -import com.intuit.tank.rest.mvc.rest.util.ServletInjector; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.rest.mvc.rest.cloud.JobEventSender; +import com.intuit.tank.rest.mvc.rest.cloud.ServletInjector; import com.intuit.tank.storage.FileData; import com.intuit.tank.storage.FileStorage; import com.intuit.tank.storage.FileStorageFactory; diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java index 553e3b939..827caec5b 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/services/filters/FilterServiceV2Impl.java @@ -25,8 +25,8 @@ import com.intuit.tank.rest.mvc.rest.models.filters.ApplyFiltersRequest; import com.intuit.tank.rest.mvc.rest.util.FilterServiceUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptFilterUtil; -import com.intuit.tank.rest.mvc.rest.util.MessageEventSender; -import com.intuit.tank.rest.mvc.rest.util.ServletInjector; +import com.intuit.tank.rest.mvc.rest.cloud.MessageEventSender; +import com.intuit.tank.rest.mvc.rest.cloud.ServletInjector; import com.intuit.tank.vm.settings.ModifiedEntityMessage; import com.intuit.tank.vm.settings.ModificationType; 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 5122fc4f3..fd33ee019 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 @@ -9,7 +9,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.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; 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 39eb310d3..9f88f4b80 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 @@ -30,14 +30,14 @@ import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceCreateOrUpdateException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceInternalServerException; import com.intuit.tank.rest.mvc.rest.controllers.errors.GenericServiceResourceNotFoundException; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRegion; import com.intuit.tank.rest.mvc.rest.util.*; -import com.intuit.tank.rest.mvc.rest.util.JobEventSender; -import com.intuit.tank.rest.mvc.rest.util.ServletInjector; +import com.intuit.tank.rest.mvc.rest.cloud.JobEventSender; +import com.intuit.tank.rest.mvc.rest.cloud.ServletInjector; import com.intuit.tank.util.TestParamUtil; import com.intuit.tank.util.TestParameterContainer; import com.intuit.tank.util.CreateDateComparator; 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 2de76aa5b..6c1400dff 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 @@ -26,8 +26,8 @@ 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.rest.mvc.rest.util.MessageEventSender; -import com.intuit.tank.rest.mvc.rest.util.ServletInjector; +import com.intuit.tank.rest.mvc.rest.cloud.MessageEventSender; +import com.intuit.tank.rest.mvc.rest.cloud.ServletInjector; import com.intuit.tank.vm.api.enumerated.ScriptDriver; import com.intuit.tank.vm.api.enumerated.TerminationPolicy; import com.intuit.tank.vm.common.TankConstants; 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 b67132051..e29a2b655 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 @@ -20,8 +20,8 @@ import com.intuit.tank.rest.mvc.rest.util.ResponseUtil; import com.intuit.tank.rest.mvc.rest.util.ScriptServiceUtil; import com.intuit.tank.script.processor.ScriptProcessor; -import com.intuit.tank.rest.mvc.rest.util.MessageEventSender; -import com.intuit.tank.rest.mvc.rest.util.ServletInjector; +import com.intuit.tank.rest.mvc.rest.cloud.MessageEventSender; +import com.intuit.tank.rest.mvc.rest.cloud.ServletInjector; import com.intuit.tank.transform.scriptGenerator.ConverterUtil; import com.intuit.tank.vm.settings.ModifiedEntityMessage; import com.intuit.tank.vm.settings.ModificationType; diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java index a5cbdf52f..73ec9eaff 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/AgentControllerTest.java @@ -10,7 +10,7 @@ import com.intuit.tank.rest.mvc.rest.services.agent.AgentServiceV2; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; import com.intuit.tank.vm.agent.messages.AgentAvailability; import com.intuit.tank.vm.agent.messages.AgentAvailabilityStatus; import com.intuit.tank.vm.agent.messages.AgentData; diff --git a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java index 7288304e9..f0a05845a 100644 --- a/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java +++ b/rest-mvc/src/test/java/com/intuit/tank/rest/mvc/rest/controllers/JobControllerTest.java @@ -8,8 +8,8 @@ package com.intuit.tank.rest.mvc.rest.controllers; import com.intuit.tank.rest.mvc.rest.services.jobs.JobServiceV2; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; import com.intuit.tank.rest.mvc.rest.models.jobs.CreateJobRequest; import com.intuit.tank.rest.mvc.rest.models.jobs.JobContainer; import com.intuit.tank.rest.mvc.rest.models.jobs.JobTO; diff --git a/rest/api/cloud/.gitignore b/rest/api/cloud/.gitignore deleted file mode 100644 index 19f2e002c..000000000 --- a/rest/api/cloud/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -/target diff --git a/rest/api/cloud/pom.xml b/rest/api/cloud/pom.xml deleted file mode 100644 index c58ffde10..000000000 --- a/rest/api/cloud/pom.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - 4.0.0 - - - com.intuit.tank - api-parent - 3.2.1-SNAPSHOT - - - cloud-api - - jar - Cloud Rest API - - - - ${project.groupId} - api - ${project.version} - - - - diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/service/v1/cloud/CloudService.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/service/v1/cloud/CloudService.java deleted file mode 100644 index a5a4e6501..000000000 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/service/v1/cloud/CloudService.java +++ /dev/null @@ -1,358 +0,0 @@ -package com.intuit.tank.api.service.v1.cloud; - -/* - * #%L - * Cloud Rest API - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -import java.util.List; -import java.util.Set; - -import javax.annotation.Nonnull; -import javax.ws.rs.Consumes; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; - -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ - -/** - * ProjectService - * - * @author dangleton - * - */ -@Path(CloudService.SERVICE_RELATIVE_PATH) -public interface CloudService { - public static final String SERVICE_RELATIVE_PATH = "/v1/cloud-service"; - - public static final String METHOD_PING = "/ping"; - public static final String METHOD_USER_ID_FROM_RANGE = "/user-id-from-range"; - - public static final String METHOD_INSTANCE_STATUS = "/instance/status"; - public static final String METHOD_JOB_STATUS = "/job/status"; - - public static final String METHOD_REPORTING_START = "/reporting/start"; - public static final String METHOD_REPORTING_STOP = "/reporting/stop"; - public static final String METHOD_REPORTING_STATUS = "/reporting/status"; - public static final String METHOD_REPORTING_SUMMARY_STATUS = "/reporting/summary/status"; - - public static final String METHOD_KILL_INSTANCE = "/instance/kill"; - public static final String METHOD_KILL_JOB = "/job/kill"; - - public static final String METHOD_START_JOB = "/job/start"; - - public static final String METHOD_STOP_INSTANCE = "/agent/stop"; - public static final String METHOD_STOP_JOB = "/job/stop"; - - public static final String METHOD_PAUSE_INSTANCE = "/agent/pause"; - public static final String METHOD_PAUSE_JOB = "/job/pause"; - - public static final String METHOD_RESTART_INSTANCE = "/agent/restart"; - public static final String METHOD_RESTART_JOB = "/job/restart"; - - public static final String METHOD_PAUSE_RAMP_JOB = "/job/ramp/pause"; - public static final String METHOD_PAUSE_RAMP_INSTANCE = "/instance/ramp/pause"; - public static final String METHOD_RESUME_RAMP_JOB = "/job/ramp/resume"; - public static final String METHOD_RESUME_RAMP_INSTANCE = "/instance/ramp/resume"; - - public static final String METHOD_GET_COST = "/costing/custom"; - public static final String METHOD_GET_COST_PREDEFINED = "/costing/predefined"; - - /** - * Test method to test if the service is up. - * - * @return non-null String value. - */ - @Path(CloudService.METHOD_PING) - @GET - @Nonnull - public String ping(); - - /** - * Gets a userId form the range specified. - * - * @param jobId - * the jobId of the range - * @param minValue - * the minValue of the range - * @param maxValue - * the max value of the range - * @return the value or throw an exception if range is exhausted. - */ - @Path(CloudService.METHOD_USER_ID_FROM_RANGE + "/{jobId}/{minValue}/{maxValue}") - @GET - @Produces({ MediaType.TEXT_PLAIN }) - public String userIdFromRange(@PathParam("jobId") String jobId, @PathParam("minValue") int minValue, - @PathParam("maxValue") int maxValue); - - /** - * - * @return - */ - @Path(CloudService.METHOD_INSTANCE_STATUS + "/{instanceId}") - @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public Response getVmStatus(@PathParam("instanceId") String instanceId); - - /** - * - * @return one of "Complete", "Gathering", or "NoData" - */ - @Path(CloudService.METHOD_REPORTING_SUMMARY_STATUS + "/{jobId}") - @GET - @Produces({ MediaType.TEXT_PLAIN }) - public Response getSummaryStatus(@PathParam("jobId") String jobId); - - /** - * - * @param jobId - * @return - */ - @Path(CloudService.METHOD_JOB_STATUS + "/{jobId}") - @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public Response getVmStatusForJob(@PathParam("jobId") String jobId); - - /** - * - * @param instanceId - * @param status - */ - @Path(CloudService.METHOD_INSTANCE_STATUS + "/{instanceId}") - @PUT - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void setVmStatus(@Nonnull @PathParam("instanceId") String instanceId, CloudVmStatus status); - - /** - * - * @param instanceId - */ - @Path(CloudService.METHOD_KILL_INSTANCE + "/{instanceId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void killInstance(@Nonnull @PathParam("instanceId") String instanceId); - - /** - * - * @param jobId - */ - @Path(CloudService.METHOD_KILL_JOB + "/{jobId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void killJob(@Nonnull @PathParam("jobId") String jobId); - - /** - * Kill All Jobs currently running - * - * @return String value. - */ - @Path(CloudService.METHOD_KILL_JOB) - @GET - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML}) - public Set killAllJobs(); - - /** - * Starts a job - * - * @param jobId - */ - @Path(CloudService.METHOD_START_JOB + "/{jobId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public String startJob(@Nonnull @PathParam("jobId") String jobId); - - /** - * - * @param instanceIds - */ - @Path(CloudService.METHOD_KILL_INSTANCE) - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @POST - public void killInstances(List instanceIds); - - /** - * Stop All Jobs currently running - * - * @return String value. - */ - @Path(CloudService.METHOD_STOP_JOB) - @GET - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML}) - public Set stopAllJobs(); - - /** - * - * @param jobId - */ - @Path(CloudService.METHOD_STOP_JOB + "/{jobId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void stopJob(@Nonnull @PathParam("jobId") String jobId); - - /** - * - * @param instanceId - */ - @Path(CloudService.METHOD_STOP_INSTANCE + "/{instanceId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void stopAgent(@Nonnull @PathParam("instanceId") String instanceId); - - /** - * - * @param instanceIds - */ - @Path(CloudService.METHOD_STOP_INSTANCE) - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void stopAgents(List instanceIds); - - /** - * - * @param jobId - */ - @Path(CloudService.METHOD_PAUSE_JOB + "/{jobId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void pauseJob(@Nonnull @PathParam("jobId") String jobId); - - /** - * - * @param instanceId - */ - @Path(CloudService.METHOD_PAUSE_INSTANCE + "/{instanceId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void pauseAgent(@Nonnull @PathParam("instanceId") String instanceId); - - /** - * - * @param group - */ - @Path(CloudService.METHOD_PAUSE_INSTANCE) - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void pauseAgents(List instanceIds); - - /** - * - * @param jobId - */ - @Path(CloudService.METHOD_RESTART_JOB + "/{jobId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void restartJob(@Nonnull @PathParam("jobId") String jobId); - - /** - * - * @param instanceId - */ - @Path(CloudService.METHOD_RESTART_INSTANCE + "/{instanceId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void restartAgent(@Nonnull @PathParam("instanceId") String instanceId); - - /** - * - * @param group - */ - @Path(CloudService.METHOD_RESTART_INSTANCE) - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void restartAgents(List instanceIds); - - /** - * - * @param instanceId - */ - @Path(CloudService.METHOD_PAUSE_RAMP_INSTANCE + "/{instanceId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void pauseRampInstance(@Nonnull @PathParam("instanceId") String instanceId); - - /** - * - * @param jobId - */ - @Path(CloudService.METHOD_PAUSE_RAMP_JOB + "/{jobId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void pauseRampJob(@Nonnull @PathParam("jobId") String jobId); - - /** - * - * @param instanceIds - */ - @Path(CloudService.METHOD_PAUSE_RAMP_INSTANCE) - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @POST - public void pauseRampInstances(List instanceIds); - - /** - * - * @param instanceId - */ - @Path(CloudService.METHOD_RESUME_RAMP_INSTANCE + "/{instanceId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void resumeRampInstance(@Nonnull @PathParam("instanceId") String instanceId); - - /** - * - * @param jobId - */ - @Path(CloudService.METHOD_RESUME_RAMP_JOB + "/{jobId}") - @POST - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - public void resumeRampJob(@Nonnull @PathParam("jobId") String jobId); - - /** - * - * @param instanceIds - */ - @Path(CloudService.METHOD_RESUME_RAMP_INSTANCE) - @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) - @POST - public void resumeRampInstances(List instanceIds); - - /** - * - * @param instanceIds - */ - @Path(CloudService.METHOD_GET_COST) - @Produces({ MediaType.TEXT_HTML }) - @GET - public String getCostingForDates(@QueryParam("startDate") String startDate, @QueryParam("endDate") String endDate); - - /** - * - * @param instanceIds - */ - @Path(CloudService.METHOD_GET_COST_PREDEFINED) - @Produces({ MediaType.TEXT_HTML }) - @GET - public String getCostingForDates( - @QueryParam("timePeriod") @DefaultValue("aws-portal-current-bill-period") String timePeriod); - -} diff --git a/rest/api/cloud/src/main/resources/META-INF/beans.xml b/rest/api/cloud/src/main/resources/META-INF/beans.xml deleted file mode 100644 index 25cc2ac7a..000000000 --- a/rest/api/cloud/src/main/resources/META-INF/beans.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/rest/api/cloud/src/main/resources/com/intuit/tank/api/model/v1/cloud/jaxb.index b/rest/api/cloud/src/main/resources/com/intuit/tank/api/model/v1/cloud/jaxb.index deleted file mode 100644 index 328a63a27..000000000 --- a/rest/api/cloud/src/main/resources/com/intuit/tank/api/model/v1/cloud/jaxb.index +++ /dev/null @@ -1,5 +0,0 @@ -CloudVmStatus -CloudVmStatusContainer -ProjectStatusContainer -UserDetail -ValidationStatus \ No newline at end of file diff --git a/rest/api/pom.xml b/rest/api/pom.xml index ea3f59eb2..9ca5abcc7 100644 --- a/rest/api/pom.xml +++ b/rest/api/pom.xml @@ -16,7 +16,6 @@ automation - cloud user datafile script diff --git a/rest/client/cloud/.gitignore b/rest/client/cloud/.gitignore deleted file mode 100644 index ea8c4bf7f..000000000 --- a/rest/client/cloud/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/rest/client/cloud/pom.xml b/rest/client/cloud/pom.xml deleted file mode 100644 index f735cdd84..000000000 --- a/rest/client/cloud/pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - 4.0.0 - - - com.intuit.tank - client-parent - 3.2.1-SNAPSHOT - - - cloud-client - - jar - Cloud Rest Client - - - - - ${project.groupId} - client-common - ${project.version} - - - - ${project.groupId} - cloud-api - ${project.version} - - - - ${project.groupId} - reporting-api - ${project.version} - - - - - diff --git a/rest/client/cloud/src/main/java/com/intuit/tank/CloudServiceClient.java b/rest/client/cloud/src/main/java/com/intuit/tank/CloudServiceClient.java deleted file mode 100644 index 0726c7329..000000000 --- a/rest/client/cloud/src/main/java/com/intuit/tank/CloudServiceClient.java +++ /dev/null @@ -1,339 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank; - -/* - * #%L - * Cloud Rest Client - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -import java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.service.v1.cloud.CloudService; -import com.intuit.tank.rest.BaseRestClient; -import com.intuit.tank.rest.RestServiceException; -import com.intuit.tank.rest.util.ServiceConsants; - -/** - * CloudServiceClient - * - * @author dangleton - * - */ -public class CloudServiceClient extends BaseRestClient { - - private static final String SERVICE_BASE_URL = ServiceConsants.REST_SERVICE_CONTEXT - + CloudService.SERVICE_RELATIVE_PATH; - - /** - * - * @param serviceUrl - */ - public CloudServiceClient(String serviceUrl) { - super(serviceUrl, null, null); - } - - /** - * - * @param serviceUrl - */ - public CloudServiceClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { - super(serviceUrl, proxyServer, proxyPort); - } - - /** - * - * @return - */ - protected String getServiceBaseUrl() { - return SERVICE_BASE_URL; - } - - /** - * {@inheritDoc} - */ - public String getSummaryStatus(String jobId) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_REPORTING_SUMMARY_STATUS, - jobId)); - Response response = webTarget.request(MediaType.TEXT_PLAIN_TYPE).get(); - exceptionHandler.checkStatusCode(response); - return response.readEntity(String.class); - } - - /** - * - * @param jobId - * @param minValue - * @param maxValue - * @return - */ - public String userIdFromRange(String jobId, int minValue, int maxValue) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_USER_ID_FROM_RANGE, jobId, - Integer.toString(minValue), Integer.toString(maxValue))); - Response response = webTarget.request(MediaType.TEXT_PLAIN_TYPE).get(); - exceptionHandler.checkStatusCode(response); - return response.getEntity().toString(); - } - - /** - * {@inheritDoc} - */ - public CloudVmStatus getVmStatus(String instanceId) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_INSTANCE_STATUS, instanceId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - return response.readEntity(CloudVmStatus.class); - } - - /** - * {@inheritDoc} - */ - public CloudVmStatusContainer getVmStatusForJob(String jobId) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_JOB_STATUS, jobId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - return response.readEntity(CloudVmStatusContainer.class); - } - - /** - * {@inheritDoc} - */ - public void setVmStatus(String instanceId, CloudVmStatus status) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_INSTANCE_STATUS, instanceId)); - Response response = webTarget.request().put(Entity.entity(status, MediaType.APPLICATION_XML_TYPE)); - exceptionHandler.checkStatusCode(response); - - } - - /** - * {@inheritDoc} - */ - public void stopInstance(String instanceId) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_INSTANCE, instanceId)); - Response response = webTarget.request().get(); - exceptionHandler.checkStatusCode(response); - - } - - /** - * {@inheritDoc} - */ - public void stopInstances(ArrayList instanceIds) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_INSTANCE)); - Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public CloudVmStatus startReportingProxy(String location) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_REPORTING_START, location)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - return response.readEntity(CloudVmStatus.class); - } - - /** - * {@inheritDoc} - */ - public void stopReportingProxy(String location) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_REPORTING_STOP, location)); - Response response = webTarget.request().get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public CloudVmStatus getReportingProxyStatus(String location) throws RestServiceException { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_REPORTING_STATUS, location)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - return response.readEntity(CloudVmStatus.class); - } - - /** - * {@inheritDoc} - */ - public void killInstance(String instanceId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_KILL_INSTANCE, instanceId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - - } - - /** - * {@inheritDoc} - */ - public void killJob(String jobId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_KILL_JOB, jobId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void killInstances(List instanceIds) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_KILL_INSTANCE)); - Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void stopJob(String jobId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_JOB, jobId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - - } - - /** - * {@inheritDoc} - */ - public void stopAgent(String instanceId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_INSTANCE, instanceId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void stopAgents(List instanceIds) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_INSTANCE)); - Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void pauseJob(String jobId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_JOB, jobId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void pauseAgent(String instanceId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_INSTANCE, instanceId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void pauseAgents(List instanceIds) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESTART_INSTANCE)); - Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void restartJob(String jobId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESTART_JOB, jobId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void restartAgent(String instanceId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESTART_INSTANCE, instanceId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void restartAgents(List instanceIds) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESTART_INSTANCE)); - Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void pauseRampJob(String jobId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_RAMP_JOB, jobId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void pauseRampAgent(String instanceId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_RAMP_INSTANCE, - instanceId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void pauseRampAgents(List instanceIds) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_RAMP_INSTANCE)); - Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void resumeRampJob(String jobId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESUME_RAMP_JOB, jobId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void resumeRampAgent(String instanceId) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESUME_RAMP_INSTANCE, - instanceId)); - Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); - exceptionHandler.checkStatusCode(response); - } - - /** - * {@inheritDoc} - */ - public void resumeRampAgents(List instanceIds) { - WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESUME_RAMP_INSTANCE)); - Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); - exceptionHandler.checkStatusCode(response); - } - -} diff --git a/rest/client/cloud/src/main/resources/META-INF/beans.xml b/rest/client/cloud/src/main/resources/META-INF/beans.xml deleted file mode 100644 index d848a504f..000000000 --- a/rest/client/cloud/src/main/resources/META-INF/beans.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/rest/client/pom.xml b/rest/client/pom.xml index c6cc93ee8..5a9a8ceec 100644 --- a/rest/client/pom.xml +++ b/rest/client/pom.xml @@ -16,7 +16,6 @@ automation - cloud user common datafile diff --git a/rest/service/cloud/.gitignore b/rest/service/cloud/.gitignore deleted file mode 100644 index ea8c4bf7f..000000000 --- a/rest/service/cloud/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/rest/service/cloud/pom.xml b/rest/service/cloud/pom.xml deleted file mode 100644 index 9b250d7c4..000000000 --- a/rest/service/cloud/pom.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - 4.0.0 - - - com.intuit.tank - service-parent - 3.2.1-SNAPSHOT - - - cloud-service - - jar - Cloud Rest Service - - - - - - ${project.groupId} - reporting-db - ${project.version} - - - - ${project.groupId} - reporting-api - ${project.version} - - - - ${project.groupId} - tank-vm-manager - ${project.version} - - - - ${project.groupId} - cloud-api - ${project.version} - - - - ${project.groupId} - service-common - ${project.version} - - - - ${project.groupId} - data-access - ${project.version} - - - - - diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudController.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudController.java deleted file mode 100644 index f0f3af89c..000000000 --- a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudController.java +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank.service.impl.v1.cloud; - -/* - * #%L - * Cloud Rest Service - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.inject.Named; - -import org.apache.commons.lang3.math.NumberUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.dao.JobInstanceDao; -import com.intuit.tank.mail.MailService; -import com.intuit.tank.project.JobInstance; -import com.intuit.tank.vm.api.enumerated.JobQueueStatus; -import com.intuit.tank.vm.api.enumerated.JobStatus; -import com.intuit.tank.vm.vmManager.VMChannel; -import com.intuit.tank.vm.vmManager.VMTerminator; - -/** - * CloudServiceV1 - * - * @author dangleton - * - */ -@Named -@RequestScoped -public class CloudController { - private static final Logger LOG = LogManager.getLogger(CloudController.class); - - @Inject - private VMTerminator terminator; - - @Inject - private VMTracker vmTracker; - - @Inject - private MailService mailService; - - @Inject - private VMChannel channel; - - /** - * {@inheritDoc} - */ - public CloudVmStatus getVmStatus(String instanceId) { - return vmTracker.getStatus(instanceId); - } - - /** - * {@inheritDoc} - */ - public void setVmStatus(final String instanceId, final CloudVmStatus status) { - vmTracker.setStatus(status); - if (status.getJobStatus() == JobStatus.Completed || status.getVmStatus() == VMStatus.terminated) { - // will terrminate instance after waiting for some cleanup time - terminator.terminate(status.getInstanceId()); - // check job status and kill off instances appropriately - checkJobStatus(status.getJobId()); - } - } - - /** - * {@inheritDoc} - */ - public CloudVmStatusContainer getVmStatusForJob(String jobId) { - return vmTracker.getVmStatusForJob(jobId); - } - - /** - * @param jobId - */ - public void checkJobStatus(String jobId) { - CloudVmStatusContainer container = vmTracker.getVmStatusForJob(jobId); - LOG.info("Checking Job Status to see if we can kill reporting instances. Container=" + container); - if (container != null) { - if (container.getEndTime() != null) { - JobInstanceDao dao = new JobInstanceDao(); - // hack to see if this is an automatino job - - // set the status of the JobInstance to finished. - JobInstance finishedJob = dao.findById(Integer.valueOf(jobId)); - if (finishedJob.getEndTime() == null) { - finishedJob.setEndTime(new Date()); - finishedJob.setStatus(JobQueueStatus.Completed); - dao.saveOrUpdate(finishedJob); - } - List statuses = Arrays.asList(JobQueueStatus.Running,JobQueueStatus.Starting ); - List instances = dao.getForStatus(statuses); - LOG.info("Checking Job Status to see if we can kill reporting instances. found running instances: " - + instances.size()); - boolean killModal = true; - boolean killNonRegional = true; - - for (JobInstance job : instances) { - CloudVmStatusContainer statusForJob = vmTracker.getVmStatusForJob(Integer.toString(job.getId())); - if (!jobId.equals(Integer.toString(job.getId())) && statusForJob != null - && statusForJob.getEndTime() == null) { - LOG.info("Found another job that is not finished: " + job); - } - } - if (killNonRegional || killModal) { - for (CloudVmStatusContainer statusForJob : vmTracker.getAllJobs()) { - if (statusForJob.getEndTime() == null && !NumberUtils.isCreatable(statusForJob.getJobId())) { - killNonRegional = false; - killModal = false; - LOG.info("Cannot kill Reporting instances because of automation job id: " - + statusForJob.getJobId()); - } - } - } - } else { - LOG.info("Container does not have end time set so cannot kill reporting instances."); - } - } - - } -} diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudServiceV1.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudServiceV1.java deleted file mode 100644 index 0dbe9e952..000000000 --- a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudServiceV1.java +++ /dev/null @@ -1,440 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank.service.impl.v1.cloud; - -/* - * #%L - * Cloud Rest Service - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Hashtable; -import java.util.List; -import java.util.Stack; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import javax.servlet.ServletContext; -import javax.ws.rs.Path; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.ResponseBuilder; - -import com.amazonaws.xray.AWSXRay; -import com.amazonaws.xray.entities.Segment; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.service.v1.cloud.CloudService; -import com.intuit.tank.dao.SummaryDataDao; -import com.intuit.tank.reporting.factory.ReportingFactory; -import com.intuit.tank.service.util.ResponseUtil; -import com.intuit.tank.service.util.ServletInjector; - -/** - * CloudServiceV1 - * - * @author dangleton - * - */ -@Path(CloudService.SERVICE_RELATIVE_PATH) -public class CloudServiceV1 implements CloudService { - - private static final Logger LOG = LogManager.getLogger(CloudServiceV1.class); - - @Context - private ServletContext servletContext; - - private DateFormat dateFormatFull = new SimpleDateFormat("MM-dd-yyyy'T'hh:mm:ss z"); - private DateFormat dateFormatShort = new SimpleDateFormat("MM-dd-yyyy"); - - private static Hashtable> stackMap = new Hashtable>(); - - /** - * {@inheritDoc} - */ - @Override - public String ping() { - return "PONG " + getClass().getSimpleName(); - } - - /** - * {@inheritDoc} - */ - @Override - public String userIdFromRange(String jobId, int minValue, int maxValue) { - Stack stack = getStack(minValue, maxValue); - if (stack.size() > 0) { - return Integer.toString(stack.pop()); - } - throw new IllegalArgumentException("Exhausted random User Ids. Range not large enough for the number of calls."); - } - - /** - * @param minId - * @param maxId - * @return - */ - private synchronized Stack getStack(Integer minId, Integer maxId) { - Stack stack = stackMap.get(minId.toString() + "-" + maxId.toString()); - if (stack == null) { - List list = IntStream.rangeClosed(minId, maxId).boxed().collect(Collectors.toList()); - Collections.shuffle(list); - stack = new Stack(); - stack.addAll(list); - } - return stack; - } - - /** - * {@inheritDoc} - */ - @Override - public Response getSummaryStatus(String jobId) { - ResponseBuilder responseBuilder = null; - try { - responseBuilder = Response.ok(); - boolean hasTable = ReportingFactory.getResultsReader().hasTimingData(jobId); - boolean hasEntries = new SummaryDataDao().findByJobId(Integer.parseInt(jobId)).size() != 0; - String status = "Gathering"; - if (hasEntries && !hasTable) { - status = "Complete"; - } else if (!hasTable && !hasEntries) { - status = "NoData"; - } - responseBuilder.entity(status); - } catch (Exception e) { - LOG.error("Error determining status: " + e.getMessage(), e); - throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); - } - responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); - return responseBuilder.build(); - } - - /** - * {@inheritDoc} - */ - @Override - public Response getVmStatus(String instanceId) { - AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); - ResponseBuilder responseBuilder = null; - try { - responseBuilder = Response.ok(); - CloudController controller = new ServletInjector().getManagedBean( - servletContext, CloudController.class); - CloudVmStatus status = controller.getVmStatus(instanceId); - responseBuilder.entity(status); - } catch (Exception e) { - LOG.error("Error Applying Filters: " + e.getMessage(), e); - throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); - } - responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); - return responseBuilder.build(); - } - - /** - * {@inheritDoc} - */ - @Override - public void setVmStatus(final String instanceId, final CloudVmStatus status) { - Segment segment = AWSXRay.getCurrentSegment(); - segment.putAnnotation("instanceId", instanceId); - segment.putAnnotation("jobId", status.getJobId()); - segment.putAnnotation("currentUsers", status.getCurrentUsers()); - segment.putAnnotation("TotalUsers", status.getTotalUsers()); - segment.putAnnotation("totalTps", status.getTotalTps()); - CloudController controller = new ServletInjector().getManagedBean( - servletContext, CloudController.class); - controller.setVmStatus(instanceId, status); - } - - /** - * {@inheritDoc} - */ - @Override - public Response getVmStatusForJob(String jobId) { - ResponseBuilder responseBuilder = null; - try { - responseBuilder = Response.ok(); - CloudController controller = new ServletInjector().getManagedBean( - servletContext, CloudController.class); - CloudVmStatusContainer container = controller.getVmStatusForJob(jobId); - responseBuilder.entity(container); - } catch (Exception e) { - LOG.error("Error Applying Filters: " + e.getMessage(), e); - throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); - } - responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); - return responseBuilder.build(); - - } - - /** - * {@inheritDoc} - */ - @Override - public String startJob(String jobId) { - AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - return controller.startJob(jobId); - } - - /** - * {@inheritDoc} - */ - @Override - public void killJob(String jobId) { - AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.killJob(jobId); - } - - - /** - * {@inheritDoc} - */ - @Override - public Set killAllJobs() { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - return controller.killAllJobs(); - } - - /** - * {@inheritDoc} - */ - @Override - public void killInstance(String instanceId) { - AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.killInstance(instanceId); - } - - /** - * {@inheritDoc} - */ - @Override - public void killInstances(List instanceIds) { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.killInstances(instanceIds); - } - - /** - * {@inheritDoc} - */ - @Override - public Set stopAllJobs() { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - return controller.stopAllJobs(); - } - - /** - * {@inheritDoc} - */ - @Override - public void stopJob(String jobId) { - AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.stopJob(jobId); - } - - /** - * {@inheritDoc} - */ - @Override - public void stopAgent(String instanceId) { - AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.stopAgent(instanceId); - - } - - /** - * {@inheritDoc} - */ - @Override - public void stopAgents(List instanceIds) { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.stopAgents(instanceIds); - } - - /** - * {@inheritDoc} - */ - @Override - public void pauseJob(String jobId) { - AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.pauseJob(jobId); - } - - /** - * {@inheritDoc} - */ - @Override - public void pauseAgent(String instanceId) { - AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.pauseAgent(instanceId); - } - - /** - * {@inheritDoc} - */ - @Override - public void pauseAgents(List instanceIds) { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.pauseAgents(instanceIds); - } - - /** - * {@inheritDoc} - */ - @Override - public void restartJob(String jobId) { - AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.restartJob(jobId); - } - - /** - * {@inheritDoc} - */ - @Override - public void restartAgent(String instanceId) { - AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.restartAgent(instanceId); - } - - /** - * {@inheritDoc} - */ - @Override - public void restartAgents(List instanceIds) { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.restartAgents(instanceIds); - } - - /** - * {@inheritDoc} - */ - @Override - public void pauseRampInstance(String instanceId) { - AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.pauseRampInstance(instanceId); - } - - /** - * {@inheritDoc} - */ - @Override - public void pauseRampJob(String jobId) { - AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.pauseRampJob(jobId); - } - - /** - * {@inheritDoc} - */ - @Override - public void pauseRampInstances(List instanceIds) { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.pauseRampInstances(instanceIds); - } - - /** - * {@inheritDoc} - */ - @Override - public void resumeRampInstance(String instanceId) { - AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.resumeRampInstance(instanceId); - } - - /** - * {@inheritDoc} - */ - @Override - public void resumeRampJob(String jobId) { - AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.resumeRampJob(jobId); - } - - /** - * {@inheritDoc} - */ - @Override - public void resumeRampInstances(List instanceIds) { - JobController controller = new ServletInjector().getManagedBean( - servletContext, JobController.class); - controller.resumeRampInstances(instanceIds); - } - - /** - * {@inheritDoc} - */ - @Override - public String getCostingForDates(String startDate, String endDate) { - // AWSCostRetriever retriever = new AWSCostRetriever(); - // Calendar start = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - // Calendar end = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - // start.setTime(parseDateString(startDate)); - // end.setTime(parseDateString(endDate)); - // ServiceUsage usage = retriever.getCustomReport(start, end); - // UsageCalculator calc = new UsageCalculator(usage); - // return AwsUtil.generateReport(calc); - throw new RuntimeException("Not implemented"); - } - - /** - * {@inheritDoc} - */ - @Override - public String getCostingForDates(String timePeriod) { - throw new RuntimeException("Not implemented"); - // AWSCostRetriever retriever = new AWSCostRetriever(); - // ServiceUsage usage = retriever.getPreDefinedReport(TimePeriodSelectChoice.valueOf(timePeriod)); - // UsageCalculator calc = new UsageCalculator(usage); - // return AwsUtil.generateReport(calc); - } - -} diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CostingCache.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CostingCache.java deleted file mode 100644 index 5e1d5a843..000000000 --- a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CostingCache.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank.service.impl.v1.cloud; - -/* - * #%L - * Cloud Rest Service - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -import javax.enterprise.context.ApplicationScoped; - -/** - * CostingCache - * - * @author dangleton - * - */ -@ApplicationScoped -public class CostingCache { - - // private Map cache = new HashMap(); - // - // public ServiceUsage getUsageForType(TimePeriodSelectChoice timePeriod) { - // ServiceUsage ret = null; - // return ret; - // } - // - // private static class UsageKey { - // private String timePeriod; - // private Calendar startDate; - // private Calendar endDate; - // /** - // * @param timePeriod - // * @param startDate - // * @param endDate - // */ - // private UsageKey(String timePeriod, Calendar startDate, Calendar endDate) { - // super(); - // this.timePeriod = timePeriod; - // this.startDate = startDate; - // this.endDate = endDate; - // } - // - // - // /** - // * {@inheritDoc} - // */ - // @Override - // public boolean equals(Object obj) { - // if (!(obj instanceof UsageKey)) { - // return false; - // } - // UsageKey o = (UsageKey) obj; - // return new EqualsBuilder().append(o.timePeriod, timePeriod).append(o.startDate, startDate).append(o.endDate, - // endDate).isEquals(); - // } - // - // /** - // * {@inheritDoc} - // */ - // @Override - // public int hashCode() { - // return new HashCodeBuilder(21, 55).append(timePeriod).append(startDate).append(endDate).toHashCode(); - // } - // } - // - // private static class UsageValue { - // private static final long VALID_FOR_TIME = 1000 * 60 * 60 * 12;//twelve hours - // private ServiceUsage usage; - // private String timePeriod; - // private long timestamp = System.currentTimeMillis(); - // - // /** - // * @param usage - // */ - // private UsageValue(ServiceUsage usage, String timePeriod) { - // super(); - // this.usage = usage; - // } - // - // /** - // * @return the usage - // */ - // public ServiceUsage getUsage() { - // return usage; - // } - // - // public boolean isValid() { - // long currTime = System.currentTimeMillis(); - // return currTime < timestamp + VALID_FOR_TIME; - // } - // } -} diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobController.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobController.java deleted file mode 100644 index 3b8803fd7..000000000 --- a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobController.java +++ /dev/null @@ -1,336 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank.service.impl.v1.cloud; - -/* - * #%L - * Cloud Rest Service - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.enterprise.context.RequestScoped; -import javax.enterprise.event.Event; -import javax.inject.Inject; -import javax.inject.Named; - -import com.amazonaws.xray.AWSXRay; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.dao.JobInstanceDao; -import com.intuit.tank.dao.WorkloadDao; -import com.intuit.tank.dao.util.ProjectDaoUtil; -import com.intuit.tank.harness.data.HDWorkload; -import com.intuit.tank.perfManager.workLoads.JobManager; -import com.intuit.tank.project.JobInstance; -import com.intuit.tank.project.Workload; -import com.intuit.tank.transform.scriptGenerator.ConverterUtil; -import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; -import com.intuit.tank.vm.api.enumerated.JobQueueStatus; -import com.intuit.tank.vm.api.enumerated.JobStatus; -import com.intuit.tank.vm.api.enumerated.VMRegion; -import com.intuit.tank.vm.event.JobEvent; -import com.intuit.tank.vm.perfManager.AgentChannel; -import com.intuit.tank.vm.settings.TankConfig; -import com.intuit.tank.vmManager.environment.amazon.AmazonInstance; - -/** - * CloudServiceV1 - * - * @author dangleton - * - */ -@Named -@RequestScoped -public class JobController { - - @Inject - private VMTracker vmTracker; - - @Inject - private JobManager jobManager; - - @Inject - private AgentChannel agentChannel; - - @Inject - private Event jobEventProducer; - - @Inject - private CloudController cloudController; - - /** - * {@inheritDoc} - */ - public String startJob(String jobId) { - AWSXRay.beginSubsegment("Start.Job." + jobId); - JobInstanceDao jobInstanceDao = new JobInstanceDao(); - JobInstance job = jobInstanceDao.findById(Integer.valueOf(jobId)); - synchronized (jobId) { - if (job.getStatus() == JobQueueStatus.Created) {// only start if new job - // save the job - job.setStatus(JobQueueStatus.Starting); - jobInstanceDao.saveOrUpdate(job); - - ProjectDaoUtil.storeScriptFile(jobId, getScriptString(job)); - - vmTracker.removeStatusForJob(jobId); - jobManager.startJob(job.getId()); - jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STARTED)); - } - } - AWSXRay.endSubsegment(); - return jobId; - } - - /** - * Use the AWS SDK to terminate instances. - * If no instances can be found, set jobStatus to Completed - */ - public void killJob(String jobId, boolean fireEvent) { - List instanceIds = getInstancesForJob(jobId); - vmTracker.stopJob(jobId); - if (instanceIds.isEmpty()) { - JobInstanceDao dao = new JobInstanceDao(); - JobInstance job = dao.findById(Integer.parseInt(jobId)); - if (job != null) { - job.setStatus(JobQueueStatus.Completed); - job.setEndTime(new Date()); - dao.saveOrUpdate(job); - } - } else { - killInstances(instanceIds); - } - - if (fireEvent) { - jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_KILLED)); - } - } - - /** - * {@inheritDoc} - */ - public void killJob(String jobId) { - killJob(jobId, true); - } - - /** - * {@inheritDoc} - */ - public Set killAllJobs() { - Set jobs = vmTracker.getAllJobs(); - for (CloudVmStatusContainer job : jobs) { - String jobId = job.getJobId(); - killJob(jobId, true); - } - return jobs; - } - - /** - * {@inheritDoc} - */ - public void killInstance(String instanceId) { killInstances(Collections.singletonList(instanceId)); } - - /** - * {@inheritDoc} - */ - public void killInstances(List instanceIds) { - agentChannel.killAgents(instanceIds); - - if (!vmTracker.isDevMode()) { - for (VMRegion region : new TankConfig().getVmManagerConfig().getRegions()) { - AmazonInstance amzInstance = new AmazonInstance(region); - amzInstance.killInstances(instanceIds); - } - } - String jobId = null; - for (String instanceId : instanceIds) { - CloudVmStatus status = new CloudVmStatus(vmTracker.getStatus(instanceId)); - status.setCurrentUsers(0); - status.setEndTime(new Date()); - status.setJobStatus(JobStatus.Completed); - status.setVmStatus(VMStatus.terminated); - vmTracker.setStatus(status); - jobId = status.getJobId(); - } - if (jobId != null) { - cloudController.checkJobStatus(jobId); - } - } - - /** - * {@inheritDoc} - */ - public Set stopAllJobs() { - Set jobs = vmTracker.getAllJobs(); - for (CloudVmStatusContainer job : jobs) { - String jobId = (job).getJobId(); - List instanceIds = getInstancesForJob(jobId); - vmTracker.stopJob(jobId); - stopAgents(instanceIds); - jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STOPPED)); - } - return jobs; - } - - /** - * {@inheritDoc} - */ - public void stopJob(String jobId) { - List instanceIds = getInstancesForJob(jobId); - vmTracker.stopJob(jobId); - stopAgents(instanceIds); - jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STOPPED)); - } - - /** - * {@inheritDoc} - */ - public void stopAgent(String instanceId) { - stopAgents(Collections.singletonList(instanceId)); - - } - - /** - * {@inheritDoc} - */ - public void stopAgents(List instanceIds) { - agentChannel.stopAgents(instanceIds); - } - - /** - * {@inheritDoc} - */ - public void pauseJob(String jobId) { - List instanceIds = getInstancesForJob(jobId); - pauseAgents(instanceIds); - jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_PAUSED)); - } - - /** - * {@inheritDoc} - */ - public void pauseAgent(String instanceId) { - pauseAgents(Collections.singletonList(instanceId)); - } - - /** - * {@inheritDoc} - */ - public void pauseAgents(List instanceIds) { - agentChannel.pauseAgents(instanceIds); - } - - /** - * {@inheritDoc} - */ - public void restartJob(String jobId) { - List instanceIds = getInstancesForJob(jobId); - restartAgents(instanceIds); - jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_RESUMED)); - } - - /** - * {@inheritDoc} - */ - public void restartAgent(String instanceId) { - restartAgents(Collections.singletonList(instanceId)); - } - - /** - * {@inheritDoc} - */ - public void restartAgents(List instanceIds) { - agentChannel.restartAgents(instanceIds); - } - - /** - * {@inheritDoc} - */ - public void pauseRampInstance(String instanceId) { - pauseRampInstances(Collections.singletonList(instanceId)); - } - - /** - * {@inheritDoc} - */ - public void pauseRampJob(String jobId) { - List instanceIds = getInstancesForJob(jobId); - pauseRampInstances(instanceIds); - jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.RAMP_PAUSED)); - } - - /** - * {@inheritDoc} - */ - public void pauseRampInstances(List instanceIds) { - agentChannel.pauseRamp(instanceIds); - } - - /** - * {@inheritDoc} - */ - public void resumeRampInstance(String instanceId) { - resumeRampInstances(Collections.singletonList(instanceId)); - } - - /** - * {@inheritDoc} - */ - public void resumeRampJob(String jobId) { - List instanceIds = getInstancesForJob(jobId); - resumeRampInstances(instanceIds); - jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.RAMP_RESUMED)); - } - - /** - * {@inheritDoc} - */ - public void resumeRampInstances(List instanceIds) { - agentChannel.resumeRamp(instanceIds); - } - - /** - * @param jobId - * @return - */ - private List getInstancesForJob(String jobId) { - List instanceIds = new ArrayList(); - CloudVmStatusContainer statuses = vmTracker.getVmStatusForJob(jobId); - if (statuses != null) { - instanceIds = statuses.getStatuses().stream().map(CloudVmStatus::getInstanceId).collect(Collectors.toList()); - } - return instanceIds; - } - - /** - * @param job - * @return - */ - public static String getScriptString(JobInstance job) { - WorkloadDao dao = new WorkloadDao(); - Workload workload = dao.findById(job.getWorkloadId()); - workload.getTestPlans(); - dao.loadScriptsForWorkload(workload); - HDWorkload hdWorkload = ConverterUtil.convertWorkload(workload, job); - return ConverterUtil.getWorkloadXML(hdWorkload); - } - -} diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobListener.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobListener.java deleted file mode 100644 index f87428bbb..000000000 --- a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobListener.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright 2011 Intuit Inc. All Rights Reserved - */ -package com.intuit.tank.service.impl.v1.cloud; - -/* - * #%L - * Cloud Rest Service - * %% - * Copyright (C) 2011 - 2015 Intuit Inc. - * %% - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * #L% - */ - -import java.io.Serializable; - -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.event.Observes; -import javax.enterprise.inject.Instance; -import javax.inject.Inject; -import javax.inject.Named; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; -import com.intuit.tank.vm.event.JobEvent; - -/** - * JobListener - * - * @author dangleton - * - */ -@Named -@ApplicationScoped -public class JobListener implements Serializable { - - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LogManager.getLogger(JobListener.class); - - @Inject - private Instance controllerSource; - - public void observerJobKillRequest(@Observes JobEvent request) { - LOG.info("Got Job Event: " + request); - if (request.getEvent() == JobLifecycleEvent.JOB_ABORTED) { - controllerSource.get().killJob(request.getJobId(), false); - } - } -} diff --git a/rest/service/cloud/src/main/resources/META-INF/beans.xml b/rest/service/cloud/src/main/resources/META-INF/beans.xml deleted file mode 100644 index 0da69df74..000000000 --- a/rest/service/cloud/src/main/resources/META-INF/beans.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/rest/service/cloud/src/test/java/com/intuit/tank/service/impl/v1/cloud/CloudSercieV1Test.java b/rest/service/cloud/src/test/java/com/intuit/tank/service/impl/v1/cloud/CloudSercieV1Test.java deleted file mode 100644 index 22d3a5c4f..000000000 --- a/rest/service/cloud/src/test/java/com/intuit/tank/service/impl/v1/cloud/CloudSercieV1Test.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.intuit.tank.service.impl.v1.cloud; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.MockitoAnnotations; - -import static org.junit.jupiter.api.Assertions.*; - -public class CloudSercieV1Test { - - @InjectMocks - CloudServiceV1 cloudServiceV1; - - private AutoCloseable closeable; - - @BeforeEach - void initService() { - closeable = MockitoAnnotations.openMocks(this); - } - - @AfterEach - void closeService() throws Exception { - closeable.close(); - } - - @Test - public void testPing() { - assertEquals("PONG CloudServiceV1", cloudServiceV1.ping()); - } - - @Test - public void testUserIdFromRangeEmpty() { - assertEquals("0",cloudServiceV1.userIdFromRange("0", 0, 0)); - } - - @Test - public void testUserIdFromRange() { - String result = cloudServiceV1.userIdFromRange("0", 0, 10); - assertTrue(Integer.parseInt(result) >= 0 && Integer.parseInt(result) <= 10); - } - - @Test - public void testCostingForDates_1() { - assertThrows(RuntimeException.class, () -> { - cloudServiceV1.getCostingForDates("", ""); - }); - } - - @Test - public void testCostingForDates_2() { - assertThrows(RuntimeException.class, () -> { - cloudServiceV1.getCostingForDates(""); - }); - } - -} diff --git a/rest/service/pom.xml b/rest/service/pom.xml index c3a85bed5..ee12d4265 100644 --- a/rest/service/pom.xml +++ b/rest/service/pom.xml @@ -16,7 +16,6 @@ automation - cloud user datafile script diff --git a/rest/service/reporting/pom.xml b/rest/service/reporting/pom.xml index 2cbfcf600..90661c946 100644 --- a/rest/service/reporting/pom.xml +++ b/rest/service/reporting/pom.xml @@ -15,13 +15,6 @@ Reporting Rest Service Implementation - - - ${project.groupId} - cloud-api - ${project.version} - - ${project.groupId} report-api diff --git a/tank_vmManager/pom.xml b/tank_vmManager/pom.xml index 5592d2a4d..53195ce61 100644 --- a/tank_vmManager/pom.xml +++ b/tank_vmManager/pom.xml @@ -34,12 +34,6 @@ ${project.version} - - ${project.groupId} - cloud-api - ${project.version} - - ${project.groupId} data-access diff --git a/tank_vmManager/src/main/java/com/intuit/tank/perfManager/workLoads/JobManager.java b/tank_vmManager/src/main/java/com/intuit/tank/perfManager/workLoads/JobManager.java index ab4f6fbd5..698bc0f0d 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/perfManager/workLoads/JobManager.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/perfManager/workLoads/JobManager.java @@ -42,10 +42,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.VMTracker; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.dao.DataFileDao; import com.intuit.tank.dao.JobInstanceDao; import com.intuit.tank.project.DataFile; diff --git a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/AgentWatchdog.java b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/AgentWatchdog.java index 64e0b60b5..cccb6aefa 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/AgentWatchdog.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/AgentWatchdog.java @@ -21,16 +21,16 @@ import java.util.stream.Collectors; import com.amazonaws.xray.AWSXRay; +import com.intuit.tank.vm.vmManager.VMTracker; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.dao.VMImageDao; import com.intuit.tank.project.VMInstance; import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; diff --git a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/CloudWatchObserver.java b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/CloudWatchObserver.java index defd06850..d61464b07 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/CloudWatchObserver.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/CloudWatchObserver.java @@ -24,12 +24,12 @@ import javax.enterprise.event.Reception; import javax.inject.Inject; +import com.intuit.tank.vm.vmManager.VMTracker; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; import com.intuit.tank.dao.JobInstanceDao; import com.intuit.tank.dao.JobNotificationDao; import com.intuit.tank.project.EntityVersion; diff --git a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VMTerminatorImpl.java b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VMTerminatorImpl.java index e4b258f7b..d1e9813a5 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VMTerminatorImpl.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VMTerminatorImpl.java @@ -22,10 +22,10 @@ import javax.annotation.Nonnull; import javax.inject.Inject; +import com.intuit.tank.vm.vmManager.VMTracker; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; import com.intuit.tank.vm.vmManager.VMChannel; import com.intuit.tank.vm.vmManager.VMTerminator; diff --git a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VMTrackerImpl.java b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VMTrackerImpl.java index 4c4bed1a8..457746bd0 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VMTrackerImpl.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VMTrackerImpl.java @@ -41,15 +41,15 @@ import javax.inject.Named; import com.amazonaws.xray.AWSXRay; +import com.intuit.tank.vm.vmManager.VMTracker; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.ProjectStatusContainer; -import com.intuit.tank.api.model.v1.cloud.VMStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.ProjectStatusContainer; +import com.intuit.tank.vm.vmManager.models.VMStatus; import com.intuit.tank.dao.JobInstanceDao; import com.intuit.tank.dao.WorkloadDao; import com.intuit.tank.project.JobInstance; diff --git a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VmMessageProcessorImpl.java b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VmMessageProcessorImpl.java index 164f9c2a2..8becc3508 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VmMessageProcessorImpl.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/VmMessageProcessorImpl.java @@ -17,16 +17,10 @@ import javax.inject.Inject; import com.amazonaws.xray.AWSXRay; +import com.intuit.tank.vm.vmManager.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.vm.vmManager.VMInstanceRequest; -import com.intuit.tank.vm.vmManager.VMJobRequest; -import com.intuit.tank.vm.vmManager.VMKillRequest; -import com.intuit.tank.vm.vmManager.VMRequest; -import com.intuit.tank.vm.vmManager.VMUpdateStateRequest; -import com.intuit.tank.vm.vmManager.VmMessageProcessor; import com.intuit.tank.vmManager.environment.CreateInstance; import com.intuit.tank.vmManager.environment.JobRequest; import com.intuit.tank.vmManager.environment.KillInstance; diff --git a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/environment/CreateInstance.java b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/environment/CreateInstance.java index fd11b5b66..9da50ee5c 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/environment/CreateInstance.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/environment/CreateInstance.java @@ -15,15 +15,13 @@ import java.util.List; -import com.amazonaws.xray.AWSXRay; -import com.amazonaws.xray.entities.Entity; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.VMTracker; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.dao.VMImageDao; import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.api.enumerated.VMImageType; diff --git a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/environment/JobRequest.java b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/environment/JobRequest.java index 3b82b754d..56a477e63 100644 --- a/tank_vmManager/src/main/java/com/intuit/tank/vmManager/environment/JobRequest.java +++ b/tank_vmManager/src/main/java/com/intuit/tank/vmManager/environment/JobRequest.java @@ -15,15 +15,13 @@ import java.util.List; -import com.amazonaws.xray.AWSXRay; -import com.amazonaws.xray.entities.Entity; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.VMTracker; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.dao.VMImageDao; import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.api.enumerated.VMImageType; diff --git a/tank_vmManager/src/test/java/com/intuit/tank/vmManager/AgentWatchdogTest.java b/tank_vmManager/src/test/java/com/intuit/tank/vmManager/AgentWatchdogTest.java index b764002ca..04296e289 100644 --- a/tank_vmManager/src/test/java/com/intuit/tank/vmManager/AgentWatchdogTest.java +++ b/tank_vmManager/src/test/java/com/intuit/tank/vmManager/AgentWatchdogTest.java @@ -1,15 +1,15 @@ package com.intuit.tank.vmManager; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.api.enumerated.VMImageType; import com.intuit.tank.vm.api.enumerated.VMRegion; import com.intuit.tank.vm.vmManager.VMInformation; import com.intuit.tank.vm.vmManager.VMInstanceRequest; +import com.intuit.tank.vm.vmManager.VMTracker; import com.intuit.tank.vmManager.environment.amazon.AmazonInstance; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java b/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java index 57dc576f3..fe99bc4a1 100644 --- a/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java @@ -68,6 +68,9 @@ public class ProjectDescriptionBean extends SelectableBean implements S public void init() { tablePrefs = new TablePreferences(userPrefs.getPreferences().getProjectTableColumns()); tablePrefs.registerListener(userPrefs); + messages.warn("Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + + "download the newest version of Tank tools under the 'Tools' tab. Please refer to the Tank V2 API documentation " + + "under 'Help' for more details on the new features."); } public void deleteSelectedProject() { diff --git a/web/web_support/src/main/java/com/intuit/tank/agent/AgentBean.java b/web/web_support/src/main/java/com/intuit/tank/agent/AgentBean.java index ffb76a473..ce941d799 100644 --- a/web/web_support/src/main/java/com/intuit/tank/agent/AgentBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/agent/AgentBean.java @@ -23,9 +23,9 @@ import org.apache.commons.lang3.time.DateFormatUtils; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.VMTracker; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; import com.intuit.tank.dao.JobQueueDao; import com.intuit.tank.project.JobQueue; import com.intuit.tank.vmManager.VMTrackerImpl; diff --git a/web/web_support/src/main/java/com/intuit/tank/job/ActJobNodeBean.java b/web/web_support/src/main/java/com/intuit/tank/job/ActJobNodeBean.java index cf4a60dd0..5dd106d86 100644 --- a/web/web_support/src/main/java/com/intuit/tank/job/ActJobNodeBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/job/ActJobNodeBean.java @@ -17,10 +17,10 @@ import java.util.List; import java.util.stream.Collectors; -import com.intuit.tank.api.model.v1.cloud.VMStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; import org.apache.commons.lang3.time.FastDateFormat; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; import com.intuit.tank.project.JobInstance; public class ActJobNodeBean extends JobNodeBean { diff --git a/web/web_support/src/main/java/com/intuit/tank/job/JobNodeBean.java b/web/web_support/src/main/java/com/intuit/tank/job/JobNodeBean.java index faadf02cf..bf05b3bfe 100644 --- a/web/web_support/src/main/java/com/intuit/tank/job/JobNodeBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/job/JobNodeBean.java @@ -22,8 +22,8 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; -import com.intuit.tank.api.model.v1.cloud.UserDetail; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.models.UserDetail; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.auth.Security; import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.settings.AccessRight; diff --git a/web/web_support/src/main/java/com/intuit/tank/job/JobQueueAction.java b/web/web_support/src/main/java/com/intuit/tank/job/JobQueueAction.java index f17f8d6de..2bf6af9dd 100644 --- a/web/web_support/src/main/java/com/intuit/tank/job/JobQueueAction.java +++ b/web/web_support/src/main/java/com/intuit/tank/job/JobQueueAction.java @@ -18,7 +18,7 @@ import javax.inject.Named; import com.amazonaws.xray.AWSXRay; -import com.intuit.tank.service.impl.v1.cloud.JobController; +import com.intuit.tank.rest.mvc.rest.cloud.JobEventSender; import com.intuit.tank.vm.api.enumerated.JobQueueStatus; import com.intuit.tank.vm.api.enumerated.JobStatus; @@ -27,7 +27,7 @@ public class JobQueueAction { @Inject - private JobController controller; + private JobEventSender controller; /** * Runs the job for the given jobId diff --git a/web/web_support/src/main/java/com/intuit/tank/job/JobStatusHelper.java b/web/web_support/src/main/java/com/intuit/tank/job/JobStatusHelper.java index 134584a5e..097e8fbf6 100644 --- a/web/web_support/src/main/java/com/intuit/tank/job/JobStatusHelper.java +++ b/web/web_support/src/main/java/com/intuit/tank/job/JobStatusHelper.java @@ -1,6 +1,6 @@ package com.intuit.tank.job; -import com.intuit.tank.api.model.v1.cloud.VMStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; /* * #%L diff --git a/web/web_support/src/main/java/com/intuit/tank/job/ProjectNodeBean.java b/web/web_support/src/main/java/com/intuit/tank/job/ProjectNodeBean.java index 96ce22f79..55df77929 100644 --- a/web/web_support/src/main/java/com/intuit/tank/job/ProjectNodeBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/job/ProjectNodeBean.java @@ -18,7 +18,7 @@ import java.util.UUID; import java.util.stream.Collectors; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.project.Project; import com.intuit.tank.vm.api.enumerated.JobQueueStatus; diff --git a/web/web_support/src/main/java/com/intuit/tank/job/VMNodeBean.java b/web/web_support/src/main/java/com/intuit/tank/job/VMNodeBean.java index 8a2db5918..dca90ac51 100644 --- a/web/web_support/src/main/java/com/intuit/tank/job/VMNodeBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/job/VMNodeBean.java @@ -18,7 +18,7 @@ import org.apache.commons.lang3.time.FastDateFormat; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; public class VMNodeBean extends JobNodeBean { diff --git a/web/web_support/src/main/java/com/intuit/tank/notification/NotificationContextBuilder.java b/web/web_support/src/main/java/com/intuit/tank/notification/NotificationContextBuilder.java index 56b849c9a..0c0e6f6e2 100644 --- a/web/web_support/src/main/java/com/intuit/tank/notification/NotificationContextBuilder.java +++ b/web/web_support/src/main/java/com/intuit/tank/notification/NotificationContextBuilder.java @@ -49,10 +49,10 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.VMTracker; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.api.service.v1.report.ReportService; import com.intuit.tank.dao.DataFileDao; import com.intuit.tank.dao.JobInstanceDao; diff --git a/web/web_support/src/main/java/com/intuit/tank/notification/NotificationRunner.java b/web/web_support/src/main/java/com/intuit/tank/notification/NotificationRunner.java index 0141c419d..7fef3b5aa 100644 --- a/web/web_support/src/main/java/com/intuit/tank/notification/NotificationRunner.java +++ b/web/web_support/src/main/java/com/intuit/tank/notification/NotificationRunner.java @@ -27,7 +27,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; +import com.intuit.tank.vm.vmManager.VMTracker; import com.intuit.tank.dao.JobInstanceDao; import com.intuit.tank.dao.JobNotificationDao; import com.intuit.tank.mail.MailService; diff --git a/web/web_support/src/main/java/com/intuit/tank/notification/NotificationSender.java b/web/web_support/src/main/java/com/intuit/tank/notification/NotificationSender.java index 1fc188c43..97d78ae96 100644 --- a/web/web_support/src/main/java/com/intuit/tank/notification/NotificationSender.java +++ b/web/web_support/src/main/java/com/intuit/tank/notification/NotificationSender.java @@ -27,7 +27,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.intuit.tank.api.cloud.VMTracker; +import com.intuit.tank.vm.vmManager.VMTracker; import com.intuit.tank.mail.MailService; import com.intuit.tank.vm.event.JobEvent; diff --git a/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java b/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java index 184278bbf..a3a1d4c51 100644 --- a/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java @@ -48,12 +48,12 @@ import com.intuit.tank.PreferencesBean; import com.intuit.tank.PropertyComparer; import com.intuit.tank.PropertyComparer.SortOrder; -import com.intuit.tank.api.cloud.VMTracker; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.ProjectStatusContainer; -import com.intuit.tank.api.model.v1.cloud.UserDetail; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.VMTracker; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.ProjectStatusContainer; +import com.intuit.tank.vm.vmManager.models.UserDetail; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.auth.Security; import com.intuit.tank.dao.JobInstanceDao; import com.intuit.tank.dao.JobQueueDao; diff --git a/web/web_support/src/test/java/com/intuit/tank/job/ActJobNodeBeanTest.java b/web/web_support/src/test/java/com/intuit/tank/job/ActJobNodeBeanTest.java index be210050b..54431df82 100644 --- a/web/web_support/src/test/java/com/intuit/tank/job/ActJobNodeBeanTest.java +++ b/web/web_support/src/test/java/com/intuit/tank/job/ActJobNodeBeanTest.java @@ -20,10 +20,10 @@ import org.apache.commons.lang3.time.FastDateFormat; import org.junit.jupiter.api.Test; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.project.JobConfiguration; import com.intuit.tank.project.JobInstance; import com.intuit.tank.project.Workload; diff --git a/web/web_support/src/test/java/com/intuit/tank/job/JobNodeBeanTest.java b/web/web_support/src/test/java/com/intuit/tank/job/JobNodeBeanTest.java index f39229ee6..d9f8bd9d0 100644 --- a/web/web_support/src/test/java/com/intuit/tank/job/JobNodeBeanTest.java +++ b/web/web_support/src/test/java/com/intuit/tank/job/JobNodeBeanTest.java @@ -23,11 +23,8 @@ import static org.junit.jupiter.api.Assertions.*; -import com.intuit.tank.api.model.v1.cloud.UserDetail; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; -import com.intuit.tank.auth.Security; -import com.intuit.tank.job.JobNodeBean; -import com.intuit.tank.job.ProjectNodeBean; +import com.intuit.tank.vm.vmManager.models.UserDetail; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.project.Project; /** diff --git a/web/web_support/src/test/java/com/intuit/tank/job/VMNodeBeanTest.java b/web/web_support/src/test/java/com/intuit/tank/job/VMNodeBeanTest.java index 3c25279eb..08ad51cac 100644 --- a/web/web_support/src/test/java/com/intuit/tank/job/VMNodeBeanTest.java +++ b/web/web_support/src/test/java/com/intuit/tank/job/VMNodeBeanTest.java @@ -22,12 +22,9 @@ import static org.junit.jupiter.api.Assertions.*; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.api.model.v1.cloud.UserDetail; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; -import com.intuit.tank.job.JobNodeBean; -import com.intuit.tank.job.VMNodeBean; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.vm.vmManager.models.ValidationStatus; import com.intuit.tank.vm.api.enumerated.JobStatus; import com.intuit.tank.vm.api.enumerated.VMImageType; import com.intuit.tank.vm.api.enumerated.VMRegion; diff --git a/web/web_support/src/test/java/com/intuit/tank/notification/NotificationRunnerTest.java b/web/web_support/src/test/java/com/intuit/tank/notification/NotificationRunnerTest.java index 8bf98905c..91fe8674d 100644 --- a/web/web_support/src/test/java/com/intuit/tank/notification/NotificationRunnerTest.java +++ b/web/web_support/src/test/java/com/intuit/tank/notification/NotificationRunnerTest.java @@ -17,9 +17,8 @@ import static org.junit.jupiter.api.Assertions.*; -import com.intuit.tank.api.cloud.VMTracker; +import com.intuit.tank.vm.vmManager.VMTracker; import com.intuit.tank.mail.MailService; -import com.intuit.tank.notification.NotificationRunner; import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; import com.intuit.tank.vm.event.JobEvent; import com.intuit.tank.vmManager.VMTrackerImpl; diff --git a/web/web_support/src/test/java/com/intuit/tank/project/JobTreeTableBeanTest.java b/web/web_support/src/test/java/com/intuit/tank/project/JobTreeTableBeanTest.java index 179255a28..055cb297a 100644 --- a/web/web_support/src/test/java/com/intuit/tank/project/JobTreeTableBeanTest.java +++ b/web/web_support/src/test/java/com/intuit/tank/project/JobTreeTableBeanTest.java @@ -19,7 +19,7 @@ import com.amazonaws.xray.AWSXRay; import com.intuit.tank.PreferencesBean; -import com.intuit.tank.api.cloud.VMTracker; +import com.intuit.tank.vm.vmManager.VMTracker; import com.intuit.tank.auth.Security; import com.intuit.tank.dao.JobQueueDao; import com.intuit.tank.dao.ProjectDao; diff --git a/web/web_ui/src/main/webapp/projects/index.xhtml b/web/web_ui/src/main/webapp/projects/index.xhtml index 207fe71ab..5c8195c10 100644 --- a/web/web_ui/src/main/webapp/projects/index.xhtml +++ b/web/web_ui/src/main/webapp/projects/index.xhtml @@ -35,7 +35,7 @@
- + From 101e509050295dddfac3bfdc9b50b494954ecbb4 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 00:11:00 -0700 Subject: [PATCH 30/73] update pom for logging --- pom.xml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 026bc5bd4..bffa45c40 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 2.7.6 5.3.25 2.7.6 - 2.20.0 + 3.10.1 @@ -849,18 +849,22 @@ org.springframework.boot spring-boot-starter-webflux - - - org.apache.logging.log4j - log4j-to-slf4j - - ${version.spring-webflux} + + org.springframework.boot + spring-boot-starter-log4j2 + 2.10.0 + + + org.apache.logging.log4j + log4j-to-slf4j + 2.0.2 + org.apache.logging.log4j log4j-slf4j-impl - ${version.log4j} + 2.0.2 From abb65a0732469629b0cd8bce0d24e9291d46847c Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 00:16:41 -0700 Subject: [PATCH 31/73] vmTracker models moved to api --- .../resources/com.intuit.tank.vmManager.models/jaxb.index | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 api/src/main/resources/com.intuit.tank.vmManager.models/jaxb.index diff --git a/api/src/main/resources/com.intuit.tank.vmManager.models/jaxb.index b/api/src/main/resources/com.intuit.tank.vmManager.models/jaxb.index new file mode 100644 index 000000000..328a63a27 --- /dev/null +++ b/api/src/main/resources/com.intuit.tank.vmManager.models/jaxb.index @@ -0,0 +1,5 @@ +CloudVmStatus +CloudVmStatusContainer +ProjectStatusContainer +UserDetail +ValidationStatus \ No newline at end of file From b44a5c59ba001389ba019d1a82ad8749cf489d62 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 00:25:38 -0700 Subject: [PATCH 32/73] updating import ref to cloud --- .../java/com/intuit/tank/rest/mvc/TankAPIApplication.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java index 588b2bba3..6a3d3d1aa 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java @@ -7,8 +7,8 @@ */ package com.intuit.tank.rest.mvc; -import com.intuit.tank.rest.mvc.rest.util.JobEventListener; -import com.intuit.tank.rest.mvc.rest.util.JobEventSender; +import com.intuit.tank.rest.mvc.rest.cloud.JobEventSender; +import com.intuit.tank.rest.mvc.rest.cloud.JobEventListener; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.servers.Server; import org.springframework.boot.SpringApplication; From c1247bc3f8727d62fbe11d82ca323581e738e6ff Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 00:35:54 -0700 Subject: [PATCH 33/73] reverting defaultcontroller --- .../rest/controllers/DefaultController.java | 53 ------------------- 1 file changed, 53 deletions(-) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DefaultController.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DefaultController.java index 791cc9522..aa6afd6af 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DefaultController.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/DefaultController.java @@ -7,30 +7,6 @@ */ package com.intuit.tank.rest.mvc.rest.controllers; -import com.intuit.tank.rest.mvc.rest.clients.AgentClient; -import com.intuit.tank.api.model.v1.cloud.VMStatus; -import com.intuit.tank.vm.agent.messages.AgentData; -import com.intuit.tank.vm.agent.messages.AgentTestStartData; -import com.intuit.tank.api.model.v1.cloud.CloudVmStatus; -import com.intuit.tank.vm.api.enumerated.JobStatus; -import com.intuit.tank.vm.api.enumerated.VMRegion; -import com.intuit.tank.vm.api.enumerated.VMImageType; -import org.springframework.web.reactive.function.client.WebClient; -import com.intuit.tank.rest.mvc.rest.clients.DataFileClient; -import com.intuit.tank.rest.mvc.rest.clients.ProjectClient; -import com.intuit.tank.rest.mvc.rest.clients.ScriptClient; -import com.intuit.tank.api.model.v1.cloud.ValidationStatus; -import com.intuit.tank.vm.agent.messages.AgentAvailability; -import com.intuit.tank.vm.agent.messages.AgentAvailabilityStatus; -import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; -import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; -import com.intuit.tank.rest.mvc.rest.models.projects.ProjectContainer; -import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; -import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; - -import java.io.InputStream; -import java.nio.charset.Charset; -import org.apache.commons.io.IOUtils; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -41,21 +17,10 @@ import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; -import java.nio.charset.StandardCharsets; -import java.util.Date; -import java.util.Map; -import java.util.List; -import java.util.concurrent.TimeUnit; - @RestController @Tag(name = "Default") public class DefaultController { - private ScriptClient scriptClient; - private AgentClient agentClient; - private ProjectClient projectClient; - private DataFileClient dataFileClient; - @GetMapping(value ="/v2/ping", produces = { MediaType.TEXT_PLAIN_VALUE } ) @Operation(description = "Pings Tank V2 API default service", summary = "Check if Tank V2 API is up") @ApiResponses(value = { @@ -65,22 +30,4 @@ public ResponseEntity ping() { return new ResponseEntity<>("PONG Tank V2 API", HttpStatus.OK); } - @GetMapping(value ="/v2/pong", produces = { MediaType.TEXT_PLAIN_VALUE } ) - public String pong() { - this.dataFileClient = new DataFileClient("http://localhost:8080/tank_war"); - -// String result = WebClient.create("http://localhost:8080/tank_war/api/v2/datafiles") -// .get() -// .uri(uriBuilder -> uriBuilder.path("/content") -// .queryParam("id", "24") -// .build()) -// .retrieve() -// .bodyToMono(String.class) -// .block(); - - - InputStream is = IOUtils.toInputStream(dataFileClient.getDatafileContent(24), StandardCharsets.UTF_8); - - return dataFileClient.getDatafileContent(24); - } } From 816d1c590c9a6aa1e1e181ca1fc9e95544a728b6 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 01:08:10 -0700 Subject: [PATCH 34/73] revert ui for now --- web/web_ui/src/main/webapp/projects/index.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/web_ui/src/main/webapp/projects/index.xhtml b/web/web_ui/src/main/webapp/projects/index.xhtml index 5c8195c10..207fe71ab 100644 --- a/web/web_ui/src/main/webapp/projects/index.xhtml +++ b/web/web_ui/src/main/webapp/projects/index.xhtml @@ -35,7 +35,7 @@
- + From 3a7b524cd61525a8eb15b9cb4ee87cc6ca0e275f Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 09:27:04 -0700 Subject: [PATCH 35/73] reverting module deletion, saving for V1 removal --- proxy-parent/owasp-proxy/pom.xml | 5 + .../tank/rest/mvc/TankAPIApplication.java | 11 +- rest/api/cloud/.gitignore | 2 + rest/api/cloud/pom.xml | 25 + .../api/model/v1/cloud/CloudVmStatus.java | 353 ++++++++++++++ .../v1/cloud/CloudVmStatusContainer.java | 220 +++++++++ .../tank/api/model/v1/cloud/Namespace.java | 31 ++ .../v1/cloud/ProjectStatusContainer.java | 152 ++++++ .../tank/api/model/v1/cloud/UserDetail.java | 91 ++++ .../tank/api/model/v1/cloud/VMStatus.java | 40 ++ .../api/model/v1/cloud/ValidationStatus.java | 230 +++++++++ .../api/service/v1/cloud/CloudService.java | 358 ++++++++++++++ .../src/main/resources/META-INF/beans.xml | 22 + .../intuit/tank/api/model/v1/cloud/jaxb.index | 5 + rest/api/pom.xml | 1 + rest/client/cloud/.gitignore | 1 + rest/client/cloud/pom.xml | 39 ++ .../com/intuit/tank/CloudServiceClient.java | 339 ++++++++++++++ .../src/main/resources/META-INF/beans.xml | 22 + rest/client/pom.xml | 1 + rest/service/cloud/.gitignore | 1 + rest/service/cloud/pom.xml | 58 +++ .../impl/v1/cloud/CloudController.java | 141 ++++++ .../service/impl/v1/cloud/CloudServiceV1.java | 440 ++++++++++++++++++ .../service/impl/v1/cloud/CostingCache.java | 102 ++++ .../service/impl/v1/cloud/JobController.java | 336 +++++++++++++ .../service/impl/v1/cloud/JobListener.java | 56 +++ .../src/main/resources/META-INF/beans.xml | 22 + .../impl/v1/cloud/CloudSercieV1Test.java | 58 +++ rest/service/pom.xml | 1 + rest/service/reporting/pom.xml | 7 + tank_vmManager/pom.xml | 6 + tools/agent_debugger/pom.xml | 6 + .../tank/tools/debugger/ActionProducer.java | 109 ++--- .../tools/debugger/AgentDebuggerFrame.java | 14 +- tools/script_filter/pom.xml | 2 +- .../tank/tools/script/ScriptFilterRunner.java | 16 +- .../src/main/webapp/META-INF/context.xml | 13 + 38 files changed, 3260 insertions(+), 76 deletions(-) create mode 100644 rest/api/cloud/.gitignore create mode 100644 rest/api/cloud/pom.xml create mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java create mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java create mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java create mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java create mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java create mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java create mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java create mode 100644 rest/api/cloud/src/main/java/com/intuit/tank/api/service/v1/cloud/CloudService.java create mode 100644 rest/api/cloud/src/main/resources/META-INF/beans.xml create mode 100644 rest/api/cloud/src/main/resources/com/intuit/tank/api/model/v1/cloud/jaxb.index create mode 100644 rest/client/cloud/.gitignore create mode 100644 rest/client/cloud/pom.xml create mode 100644 rest/client/cloud/src/main/java/com/intuit/tank/CloudServiceClient.java create mode 100644 rest/client/cloud/src/main/resources/META-INF/beans.xml create mode 100644 rest/service/cloud/.gitignore create mode 100644 rest/service/cloud/pom.xml create mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudController.java create mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudServiceV1.java create mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CostingCache.java create mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobController.java create mode 100644 rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobListener.java create mode 100644 rest/service/cloud/src/main/resources/META-INF/beans.xml create mode 100644 rest/service/cloud/src/test/java/com/intuit/tank/service/impl/v1/cloud/CloudSercieV1Test.java diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml index 3299f5e5f..42064e1c8 100755 --- a/proxy-parent/owasp-proxy/pom.xml +++ b/proxy-parent/owasp-proxy/pom.xml @@ -96,6 +96,11 @@ 0.1.2 + + org.springframework + spring-dao + 2.0.8 + diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java index 6a3d3d1aa..231a2e8f5 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java @@ -7,23 +7,16 @@ */ package com.intuit.tank.rest.mvc; -import com.intuit.tank.rest.mvc.rest.cloud.JobEventSender; -import com.intuit.tank.rest.mvc.rest.cloud.JobEventListener; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.servers.Server; import org.springframework.boot.SpringApplication; -import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.FilterType; -@OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server URL")}) -@SpringBootApplication(proxyBeanMethods = false) -@ComponentScan(basePackages = "com.intuit.tank.rest.mvc", excludeFilters = { - @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JobEventSender.class, JobEventListener.class}) -}) +@OpenAPIDefinition(servers = {@Server(url = "/tank_war", description = "Default Server URL")}) +@SpringBootApplication public class TankAPIApplication extends SpringBootServletInitializer { public static ConfigurableApplicationContext run(String[] args) { return SpringApplication.run(TankAPIApplication.class, args); diff --git a/rest/api/cloud/.gitignore b/rest/api/cloud/.gitignore new file mode 100644 index 000000000..19f2e002c --- /dev/null +++ b/rest/api/cloud/.gitignore @@ -0,0 +1,2 @@ +/target +/target diff --git a/rest/api/cloud/pom.xml b/rest/api/cloud/pom.xml new file mode 100644 index 000000000..c58ffde10 --- /dev/null +++ b/rest/api/cloud/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + + com.intuit.tank + api-parent + 3.2.1-SNAPSHOT + + + cloud-api + + jar + Cloud Rest API + + + + ${project.groupId} + api + ${project.version} + + + + diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java new file mode 100644 index 000000000..f8ff1deb7 --- /dev/null +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java @@ -0,0 +1,353 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.vm.vmManager.models; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +import com.intuit.tank.vm.api.enumerated.JobStatus; +import com.intuit.tank.vm.api.enumerated.VMImageType; +import com.intuit.tank.vm.api.enumerated.VMRegion; + +/** + * BrokerStatus + * + * @author dangleton + * + */ +@XmlRootElement(name = "cloudVm", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "CloudVm", namespace = Namespace.NAMESPACE_V1, propOrder = { + "instanceId", + "jobId", + "securityGroup", + "jobStatus", + "role", + "vmRegion", + "vmStatus", + "validationFailures", + "totalUsers", + "currentUsers", + "startTime", + "endTime", + "reportTime", + "totalTps", + "userDetails" +}) +public class CloudVmStatus implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "instanceId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private String instanceId; + + @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private String jobId; + + @XmlElement(name = "securityGroup", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private String securityGroup; + + @XmlElement(name = "jobStatus", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private JobStatus jobStatus = JobStatus.Unknown; + + @XmlElement(name = "role", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private VMImageType role = VMImageType.AGENT; + + @XmlElement(name = "vmRegion", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private VMRegion vmRegion; + + @XmlElement(name = "vmStatus", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private VMStatus vmStatus = VMStatus.unknown; + + @XmlElement(name = "validationFailures", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private ValidationStatus validationFailures; + + @XmlElement(name = "totalUsers", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int totalUsers; + + @XmlElement(name = "currentUsers", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int currentUsers; + + @XmlElement(name = "startTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private Date startTime; + + @XmlElement(name = "endTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private Date endTime; + + @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private Date reportTime; + + @XmlElement(name = "totalTps", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private int totalTps; + + @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) + @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private List userDetails = new ArrayList(); + + protected CloudVmStatus() { + } + + /** + * @param instanceId + * @param jobId + * @param securityGroup + * @param jobStatus + * @param vmStatus + * @param totalUsers + * @param currentUsers + */ + public CloudVmStatus(String instanceId, String jobId, String securityGroup, JobStatus jobStatus, VMImageType role, + VMRegion vmRegion, + VMStatus vmStatus, ValidationStatus validationFailures, + int totalUsers, int currentUsers, Date startTime, Date endTime) { + super(); + this.instanceId = instanceId; + this.jobId = jobId; + this.securityGroup = securityGroup; + this.vmRegion = vmRegion; + this.role = role; + this.jobStatus = jobStatus; + this.vmStatus = vmStatus; + this.validationFailures = validationFailures; + this.totalUsers = totalUsers; + this.currentUsers = currentUsers; + this.startTime = startTime; + this.endTime = endTime; + } + + /** + * + * @param copy + */ + public CloudVmStatus(CloudVmStatus copy) { + this.instanceId = copy.instanceId; + this.jobId = copy.jobId; + this.securityGroup = copy.securityGroup; + this.vmRegion = copy.vmRegion; + this.role = copy.role; + this.jobStatus = copy.jobStatus; + this.vmStatus = copy.vmStatus; + this.validationFailures = copy.validationFailures; + this.totalUsers = copy.totalUsers; + this.currentUsers = copy.currentUsers; + this.startTime = copy.startTime; + this.endTime = copy.endTime; + this.totalTps = copy.totalTps; + } + + /** + * @return the tpsInfo + */ + public int getTotalTps() { + return totalTps; + } + + /** + * @param totalTps + * the tpsInfo to set + */ + public void setTotalTps(int totalTps) { + this.totalTps = totalTps; + } + + /** + * @return the userDetails + */ + public List getUserDetails() { + return userDetails; + } + + /** + * @param userDetails + * the userDetails to set + */ + public void setUserDetails(List userDetails) { + this.userDetails = userDetails; + } + + /** + * @return the validationFailures + */ + public ValidationStatus getValidationFailures() { + return validationFailures; + } + + /** + * @return the instanceId + */ + public String getInstanceId() { + return instanceId; + } + + /** + * @return the vmRegion + */ + public VMRegion getVmRegion() { + return vmRegion; + } + + /** + * @return the jobId + */ + public String getJobId() { + return jobId; + } + + /** + * @return the securityGroup + */ + public String getSecurityGroup() { + return securityGroup; + } + + /** + * @return the jobStatus + */ + public JobStatus getJobStatus() { + return jobStatus; + } + + /** + * @return the vmStatus + */ + public VMStatus getVmStatus() { return vmStatus; } + + /** + * @return the totalUsers + */ + public int getTotalUsers() { + return totalUsers; + } + + /** + * @return the currentUsers + */ + public int getCurrentUsers() { + return currentUsers; + } + + /** + * @return the role + */ + public VMImageType getRole() { + return role; + } + + /** + * @return the startTime + */ + public Date getStartTime() { + return startTime; + } + + /** + * @return the endTime + */ + public Date getEndTime() { + return endTime; + } + + /** + * @return the reportTime + */ + public Date getReportTime() { + return reportTime; + } + + /** + * @param reportTime + * the reportTime to set + */ + public void setReportTime(Date reportTime) { + this.reportTime = reportTime; + } + + /** + * @param jobStatus + * the jobStatus to set + */ + public void setJobStatus(JobStatus jobStatus) { + this.jobStatus = jobStatus; + } + + /** + * @param vmStatus + * the vmStatus to set + */ + public void setVmStatus(VMStatus vmStatus) { + this.vmStatus = vmStatus; + } + + /** + * @param currentUsers + * the currentUsers to set + */ + public void setCurrentUsers(int currentUsers) { + this.currentUsers = currentUsers; + } + + /** + * @param endTime + * the endTime to set + */ + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CloudVmStatus)) { + return false; + } + CloudVmStatus o = (CloudVmStatus) obj; + return new EqualsBuilder().append(o.getInstanceId(), getInstanceId()).append(o.getJobId(), getJobId()) + .isEquals(); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder(29, 45).append(getInstanceId()).append(getJobId()).toHashCode(); + } + +} diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java new file mode 100644 index 000000000..adee83973 --- /dev/null +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java @@ -0,0 +1,220 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.vm.vmManager.models; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.bind.annotation.XmlType; + +import com.intuit.tank.vm.api.enumerated.JobQueueStatus; +import com.intuit.tank.vm.settings.TimeUtil; + +/** + * BrokerStatus + * + * @author dangleton + * + */ +@XmlRootElement(name = "cloudVmContainer", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "CloudVmStatusContainer", namespace = Namespace.NAMESPACE_V1, propOrder = { + "statuses", + "status", + "startTime", + "endTime", + "reportTime", + "jobId", + "userDetails" +}) +public class CloudVmStatusContainer implements Serializable, Comparable { + + private static final long serialVersionUID = 1L; + + @XmlElementWrapper(name = "statuses", namespace = Namespace.NAMESPACE_V1) + @XmlElement(name = "status", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Set statuses = new HashSet(); + + @XmlElement(name = "status", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private JobQueueStatus status = JobQueueStatus.Created; + + @XmlElement(name = "startTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Date startTime = new Date(); + + @XmlElement(name = "endTime", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private Date endTime; + + @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Date reportTime = new Date(); + + @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private String jobId; + + @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) + @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private List userDetails = new ArrayList(); + + @XmlTransient + private Map> detailMap = new HashMap>(); + + /** + * @FrameworkUseOnly + */ + public CloudVmStatusContainer() { + } + + /** + * @param statuses + */ + public CloudVmStatusContainer(Set statuses) { + this.statuses = statuses; + } + + public JobQueueStatus getStatus() { + return status; + } + + public void setStatus(JobQueueStatus status) { + this.status = status; + } + + public void calculateUserDetails() { + List details; + Map map = new HashMap(); + for (CloudVmStatus status : statuses) { + for (UserDetail detail : status.getUserDetails()) { + Integer val = map.get(detail.getScript()); + if (val == null) { + val = 0; + } + map.put(detail.getScript(), val + detail.getUsers()); + } + } + details = map.entrySet().stream().map(entry -> new UserDetail(entry.getKey(), entry.getValue())).sorted().collect(Collectors.toList()); + userDetails = details; + detailMap.put(TimeUtil.normalizeToPeriod(15, new Date()), details); + } + + /** + * @return the detailMap + */ + public Map> getDetailMap() { + return detailMap; + } + + /** + * @return the statuses + */ + public Set getStatuses() { + return statuses; + } + + /** + * @return the startTime + */ + public Date getStartTime() { + return startTime; + } + + /** + * @param startTime + * the startTime to set + */ + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + /** + * @return the endTime + */ + public Date getEndTime() { + return endTime; + } + + /** + * @return the userDetails + */ + public List getUserDetails() { + return userDetails; + } + + /** + * @param endTime + * the endTime to set + */ + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + /** + * @return the reportTime + */ + public Date getReportTime() { + return reportTime; + } + + /** + * @param reportTime + * the reportTime to set + */ + public void setReportTime(Date reportTime) { + this.reportTime = reportTime; + } + + /** + * @return the jobId + */ + public String getJobId() { + return jobId; + } + + /** + * @param jobId + * the jobId to set + */ + public void setJobId(String jobId) { + this.jobId = jobId; + } + + /** + * {@inheritDoc} + */ + @Override + public int compareTo(CloudVmStatusContainer o) { + if (this.startTime != null) { + return this.startTime.compareTo(o.startTime); + } else if (o.startTime != null) { + return -1; + } + // both null + return 0; + } + +} diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java new file mode 100644 index 000000000..2d0bc30a5 --- /dev/null +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java @@ -0,0 +1,31 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.vm.vmManager.models; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +/** + * Namespace + * + * @author dangleton + * + */ +public class Namespace { + + public static final String NAMESPACE_V1 = "urn:wats/domain/cloud/v1"; + + private Namespace() { + } +} diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java new file mode 100644 index 000000000..df2f75899 --- /dev/null +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java @@ -0,0 +1,152 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.vm.vmManager.models; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.bind.annotation.XmlType; + +import com.intuit.tank.vm.settings.TimeUtil; + +/** + * BrokerStatus + * + * @author dangleton + * + */ +@XmlRootElement(name = "projectStatusContainer", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ProjectStatusContainer", namespace = Namespace.NAMESPACE_V1, propOrder = { + "reportTime", + "jobId", + "userDetails" +}) +public class ProjectStatusContainer implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "reportTime", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Date reportTime = new Date(); + + @XmlElement(name = "jobId", namespace = Namespace.NAMESPACE_V1, required = false, nillable = false) + private String jobId; + + @XmlElementWrapper(name = "userDetails", namespace = Namespace.NAMESPACE_V1) + @XmlElement(name = "userDetail", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private List userDetails = null; + + @XmlTransient + private Map> detailMap = new HashMap>(); + + @XmlTransient + private Map containers = new HashMap(); + + /** + * @FrameworkUseOnly + */ + public ProjectStatusContainer() { + } + + public void addStatusContainer(CloudVmStatusContainer container) { + containers.put(container.getJobId(), container); + calculateUserDetails(); + } + + public void calculateUserDetails() { + List details; + Map map = new HashMap(); + long oldTime = System.currentTimeMillis() - 120000;// 2 minutes + Set toRemove = new HashSet(); + for (CloudVmStatusContainer container : containers.values()) { + if (container.getReportTime().getTime() < oldTime) { + toRemove.add(container.getJobId()); + } else { + for (UserDetail detail : container.getUserDetails()) { + Integer val = map.get(detail.getScript()); + if (val == null) { + val = 0; + } + map.put(detail.getScript(), val + detail.getUsers()); + } + } + } + details = map.entrySet().stream().map(entry -> new UserDetail(entry.getKey(), entry.getValue())).sorted().collect(Collectors.toList()); + userDetails = details; + detailMap.put(TimeUtil.normalizeToPeriod(15, new Date()), details); + for (String s : toRemove) { + containers.remove(s); + } + } + + /** + * @return the detailMap + */ + public Map> getDetailMap() { + return detailMap; + } + + /** + * @return the userDetails + */ + public List getUserDetails() { + return userDetails; + } + + /** + * @return the reportTime + */ + public Date getReportTime() { + return reportTime; + } + + /** + * @param reportTime + * the reportTime to set + */ + public void setReportTime(Date reportTime) { + this.reportTime = reportTime; + } + + /** + * @return the jobId + */ + public String getJobId() { + return jobId; + } + + /** + * @param jobId + * the jobId to set + */ + public void setJobId(String jobId) { + this.jobId = jobId; + } + +} diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java new file mode 100644 index 000000000..3704c0a3c --- /dev/null +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java @@ -0,0 +1,91 @@ +package com.intuit.tank.vm.vmManager.models; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.io.Serializable; +import java.util.Date; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.apache.commons.lang3.builder.ToStringBuilder; + +@XmlRootElement(name = "UserDetail", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "UserDetail", namespace = Namespace.NAMESPACE_V1) +public class UserDetail implements Serializable, Comparable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "script", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private String script; + + @XmlElement(name = "users", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Integer users; + + @XmlElement(name = "created", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private Date createTime; + + /** + * @{frameworkUseOnly + */ + public UserDetail() { + + } + + public UserDetail(String script, Integer users) { + super(); + this.script = script; + this.users = users; + this.createTime = new Date(); + } + + /** + * @return the script + */ + public String getScript() { + return script; + } + + /** + * @return the users + */ + public Integer getUsers() { + return users; + } + + /** + * @return the createTime + */ + public Date getCreateTime() { + return createTime; + } + + @Override + public int compareTo(UserDetail o) { + return script.compareTo(o.script); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java new file mode 100644 index 000000000..6c709b854 --- /dev/null +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java @@ -0,0 +1,40 @@ +package com.intuit.tank.vm.vmManager.models; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.io.Serializable; + +public enum VMStatus implements Serializable { + unknown, + starting, + pending, + rampPaused, + rebooting, + running, + stopping, + stopped, + shutting_down, + terminated; + + public static final VMStatus fromString(String value) { + VMStatus ret = null; + if ("shutting-down".equals(value)) { + ret = VMStatus.shutting_down; + } else { + ret = VMStatus.valueOf(value); + } + return ret != null ? ret : VMStatus.unknown; + } + +} diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java new file mode 100644 index 000000000..395c6eeeb --- /dev/null +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java @@ -0,0 +1,230 @@ +/** + * Copyright 2013 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.vm.vmManager.models; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; + +/** + * ValidationStatus + * + * @author psadikov + * + */ +@XmlRootElement(name = "validationCloudVm", namespace = Namespace.NAMESPACE_V1) +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "validationCloudVm", namespace = Namespace.NAMESPACE_V1, propOrder = { + "kills", + "aborts", + "gotos", + "skips", + "skipGroups", + "restarts" +}) +public class ValidationStatus implements Serializable { + + private static final long serialVersionUID = 1L; + + @XmlElement(name = "kills", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int kills; + + @XmlElement(name = "aborts", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int aborts; + + @XmlElement(name = "gotos", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int gotos; + + @XmlElement(name = "skips", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int skips; + + @XmlElement(name = "skipGroups", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int skipGroups; + + @XmlElement(name = "restarts", namespace = Namespace.NAMESPACE_V1, required = true, nillable = false) + private int restarts; + + public ValidationStatus() { + } + + /** + * + */ + public ValidationStatus(int kills, int aborts, int gotos, int skips, int skipGroups, int restarts) { + super(); + this.kills = kills; + this.aborts = aborts; + this.gotos = gotos; + this.skips = skips; + this.skipGroups = skipGroups; + this.restarts = restarts; + } + + /** + * @return total number of failures + */ + public int getTotal() { + return kills + aborts + gotos + skips + skipGroups + restarts; + } + + /** + * @return the validationKills + */ + public int getValidationKills() { + return kills; + } + + /** + * @return the validationAborts + */ + public int getValidationAborts() { + return aborts; + } + + /** + * @return the validationGotos + */ + public int getValidationGotos() { + return gotos; + } + + /** + * @return the validationSkips + */ + public int getValidationSkips() { + return skips; + } + + /** + * @return the validationSkipGroups + */ + public int getValidationSkipGroups() { + return skipGroups; + } + + /** + * @return the validationRestarts + */ + public int getValidationRestarts() { + return restarts; + } + + /** + * Add fail counts from another ValidationStatus + */ + public void addFailures(ValidationStatus other) { + this.kills += other.kills; + this.aborts += other.aborts; + this.gotos += other.gotos; + this.skips += other.skips; + this.skipGroups += other.skipGroups; + this.restarts += other.restarts; + } + + /** + * Update kill count + */ + public void addKill() { + kills++; + } + + /** + * Update abort count + */ + public void addAbort() { + aborts++; + } + + /** + * Update goto count + */ + public void addGoto() { + gotos++; + } + + /** + * Update skip count + */ + public void addSkip() { + skips++; + } + + /** + * Update skip group count + */ + public void addSkipGroup() { + skipGroups++; + } + + /** + * Update restart count + */ + public void addRestart() { + restarts++; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ValidationStatus)) { + return false; + } + ValidationStatus o = (ValidationStatus) obj; + return new EqualsBuilder() + .append(o.getValidationKills(), getValidationKills()) + .append(o.getValidationAborts(), getValidationAborts()) + .append(o.getValidationGotos(), getValidationGotos()) + .append(o.getValidationSkips(), getValidationSkips()) + .append(o.getValidationSkipGroups(), getValidationSkipGroups()) + .append(o.getValidationRestarts(), getValidationRestarts()) + .isEquals(); + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return new HashCodeBuilder(29, 37) + .append(getValidationKills()) + .append(getValidationAborts()) + .append(getValidationGotos()) + .append(getValidationSkips()) + .append(getValidationSkipGroups()) + .append(getValidationRestarts()) + .toHashCode(); + } + +} diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/service/v1/cloud/CloudService.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/service/v1/cloud/CloudService.java new file mode 100644 index 000000000..b7575852d --- /dev/null +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/service/v1/cloud/CloudService.java @@ -0,0 +1,358 @@ +package com.intuit.tank.api.service.v1.cloud; + +/* + * #%L + * Cloud Rest API + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.util.List; +import java.util.Set; + +import javax.annotation.Nonnull; +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; + +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ + +/** + * ProjectService + * + * @author dangleton + * + */ +@Path(CloudService.SERVICE_RELATIVE_PATH) +public interface CloudService { + public static final String SERVICE_RELATIVE_PATH = "/v1/cloud-service"; + + public static final String METHOD_PING = "/ping"; + public static final String METHOD_USER_ID_FROM_RANGE = "/user-id-from-range"; + + public static final String METHOD_INSTANCE_STATUS = "/instance/status"; + public static final String METHOD_JOB_STATUS = "/job/status"; + + public static final String METHOD_REPORTING_START = "/reporting/start"; + public static final String METHOD_REPORTING_STOP = "/reporting/stop"; + public static final String METHOD_REPORTING_STATUS = "/reporting/status"; + public static final String METHOD_REPORTING_SUMMARY_STATUS = "/reporting/summary/status"; + + public static final String METHOD_KILL_INSTANCE = "/instance/kill"; + public static final String METHOD_KILL_JOB = "/job/kill"; + + public static final String METHOD_START_JOB = "/job/start"; + + public static final String METHOD_STOP_INSTANCE = "/agent/stop"; + public static final String METHOD_STOP_JOB = "/job/stop"; + + public static final String METHOD_PAUSE_INSTANCE = "/agent/pause"; + public static final String METHOD_PAUSE_JOB = "/job/pause"; + + public static final String METHOD_RESTART_INSTANCE = "/agent/restart"; + public static final String METHOD_RESTART_JOB = "/job/restart"; + + public static final String METHOD_PAUSE_RAMP_JOB = "/job/ramp/pause"; + public static final String METHOD_PAUSE_RAMP_INSTANCE = "/instance/ramp/pause"; + public static final String METHOD_RESUME_RAMP_JOB = "/job/ramp/resume"; + public static final String METHOD_RESUME_RAMP_INSTANCE = "/instance/ramp/resume"; + + public static final String METHOD_GET_COST = "/costing/custom"; + public static final String METHOD_GET_COST_PREDEFINED = "/costing/predefined"; + + /** + * Test method to test if the service is up. + * + * @return non-null String value. + */ + @Path(CloudService.METHOD_PING) + @GET + @Nonnull + public String ping(); + + /** + * Gets a userId form the range specified. + * + * @param jobId + * the jobId of the range + * @param minValue + * the minValue of the range + * @param maxValue + * the max value of the range + * @return the value or throw an exception if range is exhausted. + */ + @Path(CloudService.METHOD_USER_ID_FROM_RANGE + "/{jobId}/{minValue}/{maxValue}") + @GET + @Produces({ MediaType.TEXT_PLAIN }) + public String userIdFromRange(@PathParam("jobId") String jobId, @PathParam("minValue") int minValue, + @PathParam("maxValue") int maxValue); + + /** + * + * @return + */ + @Path(CloudService.METHOD_INSTANCE_STATUS + "/{instanceId}") + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response getVmStatus(@PathParam("instanceId") String instanceId); + + /** + * + * @return one of "Complete", "Gathering", or "NoData" + */ + @Path(CloudService.METHOD_REPORTING_SUMMARY_STATUS + "/{jobId}") + @GET + @Produces({ MediaType.TEXT_PLAIN }) + public Response getSummaryStatus(@PathParam("jobId") String jobId); + + /** + * + * @param jobId + * @return + */ + @Path(CloudService.METHOD_JOB_STATUS + "/{jobId}") + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response getVmStatusForJob(@PathParam("jobId") String jobId); + + /** + * + * @param instanceId + * @param status + */ + @Path(CloudService.METHOD_INSTANCE_STATUS + "/{instanceId}") + @PUT + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void setVmStatus(@Nonnull @PathParam("instanceId") String instanceId, CloudVmStatus status); + + /** + * + * @param instanceId + */ + @Path(CloudService.METHOD_KILL_INSTANCE + "/{instanceId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void killInstance(@Nonnull @PathParam("instanceId") String instanceId); + + /** + * + * @param jobId + */ + @Path(CloudService.METHOD_KILL_JOB + "/{jobId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void killJob(@Nonnull @PathParam("jobId") String jobId); + + /** + * Kill All Jobs currently running + * + * @return String value. + */ + @Path(CloudService.METHOD_KILL_JOB) + @GET + @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML}) + public Set killAllJobs(); + + /** + * Starts a job + * + * @param jobId + */ + @Path(CloudService.METHOD_START_JOB + "/{jobId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public String startJob(@Nonnull @PathParam("jobId") String jobId); + + /** + * + * @param instanceIds + */ + @Path(CloudService.METHOD_KILL_INSTANCE) + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @POST + public void killInstances(List instanceIds); + + /** + * Stop All Jobs currently running + * + * @return String value. + */ + @Path(CloudService.METHOD_STOP_JOB) + @GET + @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML}) + public Set stopAllJobs(); + + /** + * + * @param jobId + */ + @Path(CloudService.METHOD_STOP_JOB + "/{jobId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void stopJob(@Nonnull @PathParam("jobId") String jobId); + + /** + * + * @param instanceId + */ + @Path(CloudService.METHOD_STOP_INSTANCE + "/{instanceId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void stopAgent(@Nonnull @PathParam("instanceId") String instanceId); + + /** + * + * @param instanceIds + */ + @Path(CloudService.METHOD_STOP_INSTANCE) + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void stopAgents(List instanceIds); + + /** + * + * @param jobId + */ + @Path(CloudService.METHOD_PAUSE_JOB + "/{jobId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void pauseJob(@Nonnull @PathParam("jobId") String jobId); + + /** + * + * @param instanceId + */ + @Path(CloudService.METHOD_PAUSE_INSTANCE + "/{instanceId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void pauseAgent(@Nonnull @PathParam("instanceId") String instanceId); + + /** + * + * @param group + */ + @Path(CloudService.METHOD_PAUSE_INSTANCE) + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void pauseAgents(List instanceIds); + + /** + * + * @param jobId + */ + @Path(CloudService.METHOD_RESTART_JOB + "/{jobId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void restartJob(@Nonnull @PathParam("jobId") String jobId); + + /** + * + * @param instanceId + */ + @Path(CloudService.METHOD_RESTART_INSTANCE + "/{instanceId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void restartAgent(@Nonnull @PathParam("instanceId") String instanceId); + + /** + * + * @param group + */ + @Path(CloudService.METHOD_RESTART_INSTANCE) + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void restartAgents(List instanceIds); + + /** + * + * @param instanceId + */ + @Path(CloudService.METHOD_PAUSE_RAMP_INSTANCE + "/{instanceId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void pauseRampInstance(@Nonnull @PathParam("instanceId") String instanceId); + + /** + * + * @param jobId + */ + @Path(CloudService.METHOD_PAUSE_RAMP_JOB + "/{jobId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void pauseRampJob(@Nonnull @PathParam("jobId") String jobId); + + /** + * + * @param instanceIds + */ + @Path(CloudService.METHOD_PAUSE_RAMP_INSTANCE) + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @POST + public void pauseRampInstances(List instanceIds); + + /** + * + * @param instanceId + */ + @Path(CloudService.METHOD_RESUME_RAMP_INSTANCE + "/{instanceId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void resumeRampInstance(@Nonnull @PathParam("instanceId") String instanceId); + + /** + * + * @param jobId + */ + @Path(CloudService.METHOD_RESUME_RAMP_JOB + "/{jobId}") + @POST + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void resumeRampJob(@Nonnull @PathParam("jobId") String jobId); + + /** + * + * @param instanceIds + */ + @Path(CloudService.METHOD_RESUME_RAMP_INSTANCE) + @Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @POST + public void resumeRampInstances(List instanceIds); + + /** + * + * @param instanceIds + */ + @Path(CloudService.METHOD_GET_COST) + @Produces({ MediaType.TEXT_HTML }) + @GET + public String getCostingForDates(@QueryParam("startDate") String startDate, @QueryParam("endDate") String endDate); + + /** + * + * @param instanceIds + */ + @Path(CloudService.METHOD_GET_COST_PREDEFINED) + @Produces({ MediaType.TEXT_HTML }) + @GET + public String getCostingForDates( + @QueryParam("timePeriod") @DefaultValue("aws-portal-current-bill-period") String timePeriod); + +} diff --git a/rest/api/cloud/src/main/resources/META-INF/beans.xml b/rest/api/cloud/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..25cc2ac7a --- /dev/null +++ b/rest/api/cloud/src/main/resources/META-INF/beans.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/rest/api/cloud/src/main/resources/com/intuit/tank/api/model/v1/cloud/jaxb.index b/rest/api/cloud/src/main/resources/com/intuit/tank/api/model/v1/cloud/jaxb.index new file mode 100644 index 000000000..328a63a27 --- /dev/null +++ b/rest/api/cloud/src/main/resources/com/intuit/tank/api/model/v1/cloud/jaxb.index @@ -0,0 +1,5 @@ +CloudVmStatus +CloudVmStatusContainer +ProjectStatusContainer +UserDetail +ValidationStatus \ No newline at end of file diff --git a/rest/api/pom.xml b/rest/api/pom.xml index 9ca5abcc7..ea3f59eb2 100644 --- a/rest/api/pom.xml +++ b/rest/api/pom.xml @@ -16,6 +16,7 @@ automation + cloud user datafile script diff --git a/rest/client/cloud/.gitignore b/rest/client/cloud/.gitignore new file mode 100644 index 000000000..ea8c4bf7f --- /dev/null +++ b/rest/client/cloud/.gitignore @@ -0,0 +1 @@ +/target diff --git a/rest/client/cloud/pom.xml b/rest/client/cloud/pom.xml new file mode 100644 index 000000000..f735cdd84 --- /dev/null +++ b/rest/client/cloud/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + + com.intuit.tank + client-parent + 3.2.1-SNAPSHOT + + + cloud-client + + jar + Cloud Rest Client + + + + + ${project.groupId} + client-common + ${project.version} + + + + ${project.groupId} + cloud-api + ${project.version} + + + + ${project.groupId} + reporting-api + ${project.version} + + + + + diff --git a/rest/client/cloud/src/main/java/com/intuit/tank/CloudServiceClient.java b/rest/client/cloud/src/main/java/com/intuit/tank/CloudServiceClient.java new file mode 100644 index 000000000..b6f90e336 --- /dev/null +++ b/rest/client/cloud/src/main/java/com/intuit/tank/CloudServiceClient.java @@ -0,0 +1,339 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank; + +/* + * #%L + * Cloud Rest Client + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.api.service.v1.cloud.CloudService; +import com.intuit.tank.rest.BaseRestClient; +import com.intuit.tank.rest.RestServiceException; +import com.intuit.tank.rest.util.ServiceConsants; + +/** + * CloudServiceClient + * + * @author dangleton + * + */ +public class CloudServiceClient extends BaseRestClient { + + private static final String SERVICE_BASE_URL = ServiceConsants.REST_SERVICE_CONTEXT + + CloudService.SERVICE_RELATIVE_PATH; + + /** + * + * @param serviceUrl + */ + public CloudServiceClient(String serviceUrl) { + super(serviceUrl, null, null); + } + + /** + * + * @param serviceUrl + */ + public CloudServiceClient(String serviceUrl, final String proxyServer, final Integer proxyPort) { + super(serviceUrl, proxyServer, proxyPort); + } + + /** + * + * @return + */ + protected String getServiceBaseUrl() { + return SERVICE_BASE_URL; + } + + /** + * {@inheritDoc} + */ + public String getSummaryStatus(String jobId) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_REPORTING_SUMMARY_STATUS, + jobId)); + Response response = webTarget.request(MediaType.TEXT_PLAIN_TYPE).get(); + exceptionHandler.checkStatusCode(response); + return response.readEntity(String.class); + } + + /** + * + * @param jobId + * @param minValue + * @param maxValue + * @return + */ + public String userIdFromRange(String jobId, int minValue, int maxValue) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_USER_ID_FROM_RANGE, jobId, + Integer.toString(minValue), Integer.toString(maxValue))); + Response response = webTarget.request(MediaType.TEXT_PLAIN_TYPE).get(); + exceptionHandler.checkStatusCode(response); + return response.getEntity().toString(); + } + + /** + * {@inheritDoc} + */ + public CloudVmStatus getVmStatus(String instanceId) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_INSTANCE_STATUS, instanceId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + return response.readEntity(CloudVmStatus.class); + } + + /** + * {@inheritDoc} + */ + public CloudVmStatusContainer getVmStatusForJob(String jobId) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_JOB_STATUS, jobId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + return response.readEntity(CloudVmStatusContainer.class); + } + + /** + * {@inheritDoc} + */ + public void setVmStatus(String instanceId, CloudVmStatus status) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_INSTANCE_STATUS, instanceId)); + Response response = webTarget.request().put(Entity.entity(status, MediaType.APPLICATION_XML_TYPE)); + exceptionHandler.checkStatusCode(response); + + } + + /** + * {@inheritDoc} + */ + public void stopInstance(String instanceId) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_INSTANCE, instanceId)); + Response response = webTarget.request().get(); + exceptionHandler.checkStatusCode(response); + + } + + /** + * {@inheritDoc} + */ + public void stopInstances(ArrayList instanceIds) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_INSTANCE)); + Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public CloudVmStatus startReportingProxy(String location) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_REPORTING_START, location)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + return response.readEntity(CloudVmStatus.class); + } + + /** + * {@inheritDoc} + */ + public void stopReportingProxy(String location) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_REPORTING_STOP, location)); + Response response = webTarget.request().get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public CloudVmStatus getReportingProxyStatus(String location) throws RestServiceException { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_REPORTING_STATUS, location)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + return response.readEntity(CloudVmStatus.class); + } + + /** + * {@inheritDoc} + */ + public void killInstance(String instanceId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_KILL_INSTANCE, instanceId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + + } + + /** + * {@inheritDoc} + */ + public void killJob(String jobId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_KILL_JOB, jobId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void killInstances(List instanceIds) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_KILL_INSTANCE)); + Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void stopJob(String jobId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_JOB, jobId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + + } + + /** + * {@inheritDoc} + */ + public void stopAgent(String instanceId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_INSTANCE, instanceId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void stopAgents(List instanceIds) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_STOP_INSTANCE)); + Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void pauseJob(String jobId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_JOB, jobId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void pauseAgent(String instanceId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_INSTANCE, instanceId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void pauseAgents(List instanceIds) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESTART_INSTANCE)); + Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void restartJob(String jobId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESTART_JOB, jobId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void restartAgent(String instanceId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESTART_INSTANCE, instanceId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void restartAgents(List instanceIds) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESTART_INSTANCE)); + Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void pauseRampJob(String jobId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_RAMP_JOB, jobId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void pauseRampAgent(String instanceId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_RAMP_INSTANCE, + instanceId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void pauseRampAgents(List instanceIds) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_PAUSE_RAMP_INSTANCE)); + Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void resumeRampJob(String jobId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESUME_RAMP_JOB, jobId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void resumeRampAgent(String instanceId) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESUME_RAMP_INSTANCE, + instanceId)); + Response response = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(); + exceptionHandler.checkStatusCode(response); + } + + /** + * {@inheritDoc} + */ + public void resumeRampAgents(List instanceIds) { + WebTarget webTarget = client.target(urlBuilder.buildUrl(CloudService.METHOD_RESUME_RAMP_INSTANCE)); + Response response = webTarget.request().post(Entity.entity(instanceIds, MediaType.APPLICATION_XML)); + exceptionHandler.checkStatusCode(response); + } + +} diff --git a/rest/client/cloud/src/main/resources/META-INF/beans.xml b/rest/client/cloud/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..d848a504f --- /dev/null +++ b/rest/client/cloud/src/main/resources/META-INF/beans.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/rest/client/pom.xml b/rest/client/pom.xml index 5a9a8ceec..c6cc93ee8 100644 --- a/rest/client/pom.xml +++ b/rest/client/pom.xml @@ -16,6 +16,7 @@ automation + cloud user common datafile diff --git a/rest/service/cloud/.gitignore b/rest/service/cloud/.gitignore new file mode 100644 index 000000000..ea8c4bf7f --- /dev/null +++ b/rest/service/cloud/.gitignore @@ -0,0 +1 @@ +/target diff --git a/rest/service/cloud/pom.xml b/rest/service/cloud/pom.xml new file mode 100644 index 000000000..9b250d7c4 --- /dev/null +++ b/rest/service/cloud/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + + com.intuit.tank + service-parent + 3.2.1-SNAPSHOT + + + cloud-service + + jar + Cloud Rest Service + + + + + + ${project.groupId} + reporting-db + ${project.version} + + + + ${project.groupId} + reporting-api + ${project.version} + + + + ${project.groupId} + tank-vm-manager + ${project.version} + + + + ${project.groupId} + cloud-api + ${project.version} + + + + ${project.groupId} + service-common + ${project.version} + + + + ${project.groupId} + data-access + ${project.version} + + + + + diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudController.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudController.java new file mode 100644 index 000000000..0ea35ad30 --- /dev/null +++ b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudController.java @@ -0,0 +1,141 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.service.impl.v1.cloud; + +/* + * #%L + * Cloud Rest Service + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.intuit.tank.vm.vmManager.VMTracker; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.dao.JobInstanceDao; +import com.intuit.tank.mail.MailService; +import com.intuit.tank.project.JobInstance; +import com.intuit.tank.vm.api.enumerated.JobQueueStatus; +import com.intuit.tank.vm.api.enumerated.JobStatus; +import com.intuit.tank.vm.vmManager.VMChannel; +import com.intuit.tank.vm.vmManager.VMTerminator; + +/** + * CloudServiceV1 + * + * @author dangleton + * + */ +@Named +@RequestScoped +public class CloudController { + private static final Logger LOG = LogManager.getLogger(CloudController.class); + + @Inject + private VMTerminator terminator; + + @Inject + private VMTracker vmTracker; + + @Inject + private MailService mailService; + + @Inject + private VMChannel channel; + + /** + * {@inheritDoc} + */ + public CloudVmStatus getVmStatus(String instanceId) { + return vmTracker.getStatus(instanceId); + } + + /** + * {@inheritDoc} + */ + public void setVmStatus(final String instanceId, final CloudVmStatus status) { + vmTracker.setStatus(status); + if (status.getJobStatus() == JobStatus.Completed || status.getVmStatus() == VMStatus.terminated) { + // will terrminate instance after waiting for some cleanup time + terminator.terminate(status.getInstanceId()); + // check job status and kill off instances appropriately + checkJobStatus(status.getJobId()); + } + } + + /** + * {@inheritDoc} + */ + public CloudVmStatusContainer getVmStatusForJob(String jobId) { + return vmTracker.getVmStatusForJob(jobId); + } + + /** + * @param jobId + */ + public void checkJobStatus(String jobId) { + CloudVmStatusContainer container = vmTracker.getVmStatusForJob(jobId); + LOG.info("Checking Job Status to see if we can kill reporting instances. Container=" + container); + if (container != null) { + if (container.getEndTime() != null) { + JobInstanceDao dao = new JobInstanceDao(); + // hack to see if this is an automatino job + + // set the status of the JobInstance to finished. + JobInstance finishedJob = dao.findById(Integer.valueOf(jobId)); + if (finishedJob.getEndTime() == null) { + finishedJob.setEndTime(new Date()); + finishedJob.setStatus(JobQueueStatus.Completed); + dao.saveOrUpdate(finishedJob); + } + List statuses = Arrays.asList(JobQueueStatus.Running,JobQueueStatus.Starting ); + List instances = dao.getForStatus(statuses); + LOG.info("Checking Job Status to see if we can kill reporting instances. found running instances: " + + instances.size()); + boolean killModal = true; + boolean killNonRegional = true; + + for (JobInstance job : instances) { + CloudVmStatusContainer statusForJob = vmTracker.getVmStatusForJob(Integer.toString(job.getId())); + if (!jobId.equals(Integer.toString(job.getId())) && statusForJob != null + && statusForJob.getEndTime() == null) { + LOG.info("Found another job that is not finished: " + job); + } + } + if (killNonRegional || killModal) { + for (CloudVmStatusContainer statusForJob : vmTracker.getAllJobs()) { + if (statusForJob.getEndTime() == null && !NumberUtils.isCreatable(statusForJob.getJobId())) { + killNonRegional = false; + killModal = false; + LOG.info("Cannot kill Reporting instances because of automation job id: " + + statusForJob.getJobId()); + } + } + } + } else { + LOG.info("Container does not have end time set so cannot kill reporting instances."); + } + } + + } +} diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudServiceV1.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudServiceV1.java new file mode 100644 index 000000000..cb38dcca7 --- /dev/null +++ b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CloudServiceV1.java @@ -0,0 +1,440 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.service.impl.v1.cloud; + +/* + * #%L + * Cloud Rest Service + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; +import java.util.Stack; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import javax.servlet.ServletContext; +import javax.ws.rs.Path; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; + +import com.amazonaws.xray.AWSXRay; +import com.amazonaws.xray.entities.Segment; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.api.service.v1.cloud.CloudService; +import com.intuit.tank.dao.SummaryDataDao; +import com.intuit.tank.reporting.factory.ReportingFactory; +import com.intuit.tank.service.util.ResponseUtil; +import com.intuit.tank.service.util.ServletInjector; + +/** + * CloudServiceV1 + * + * @author dangleton + * + */ +@Path(CloudService.SERVICE_RELATIVE_PATH) +public class CloudServiceV1 implements CloudService { + + private static final Logger LOG = LogManager.getLogger(CloudServiceV1.class); + + @Context + private ServletContext servletContext; + + private DateFormat dateFormatFull = new SimpleDateFormat("MM-dd-yyyy'T'hh:mm:ss z"); + private DateFormat dateFormatShort = new SimpleDateFormat("MM-dd-yyyy"); + + private static Hashtable> stackMap = new Hashtable>(); + + /** + * {@inheritDoc} + */ + @Override + public String ping() { + return "PONG " + getClass().getSimpleName(); + } + + /** + * {@inheritDoc} + */ + @Override + public String userIdFromRange(String jobId, int minValue, int maxValue) { + Stack stack = getStack(minValue, maxValue); + if (stack.size() > 0) { + return Integer.toString(stack.pop()); + } + throw new IllegalArgumentException("Exhausted random User Ids. Range not large enough for the number of calls."); + } + + /** + * @param minId + * @param maxId + * @return + */ + private synchronized Stack getStack(Integer minId, Integer maxId) { + Stack stack = stackMap.get(minId.toString() + "-" + maxId.toString()); + if (stack == null) { + List list = IntStream.rangeClosed(minId, maxId).boxed().collect(Collectors.toList()); + Collections.shuffle(list); + stack = new Stack(); + stack.addAll(list); + } + return stack; + } + + /** + * {@inheritDoc} + */ + @Override + public Response getSummaryStatus(String jobId) { + ResponseBuilder responseBuilder = null; + try { + responseBuilder = Response.ok(); + boolean hasTable = ReportingFactory.getResultsReader().hasTimingData(jobId); + boolean hasEntries = new SummaryDataDao().findByJobId(Integer.parseInt(jobId)).size() != 0; + String status = "Gathering"; + if (hasEntries && !hasTable) { + status = "Complete"; + } else if (!hasTable && !hasEntries) { + status = "NoData"; + } + responseBuilder.entity(status); + } catch (Exception e) { + LOG.error("Error determining status: " + e.getMessage(), e); + throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); + return responseBuilder.build(); + } + + /** + * {@inheritDoc} + */ + @Override + public Response getVmStatus(String instanceId) { + AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); + ResponseBuilder responseBuilder = null; + try { + responseBuilder = Response.ok(); + CloudController controller = new ServletInjector().getManagedBean( + servletContext, CloudController.class); + CloudVmStatus status = controller.getVmStatus(instanceId); + responseBuilder.entity(status); + } catch (Exception e) { + LOG.error("Error Applying Filters: " + e.getMessage(), e); + throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); + return responseBuilder.build(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setVmStatus(final String instanceId, final CloudVmStatus status) { + Segment segment = AWSXRay.getCurrentSegment(); + segment.putAnnotation("instanceId", instanceId); + segment.putAnnotation("jobId", status.getJobId()); + segment.putAnnotation("currentUsers", status.getCurrentUsers()); + segment.putAnnotation("TotalUsers", status.getTotalUsers()); + segment.putAnnotation("totalTps", status.getTotalTps()); + CloudController controller = new ServletInjector().getManagedBean( + servletContext, CloudController.class); + controller.setVmStatus(instanceId, status); + } + + /** + * {@inheritDoc} + */ + @Override + public Response getVmStatusForJob(String jobId) { + ResponseBuilder responseBuilder = null; + try { + responseBuilder = Response.ok(); + CloudController controller = new ServletInjector().getManagedBean( + servletContext, CloudController.class); + CloudVmStatusContainer container = controller.getVmStatusForJob(jobId); + responseBuilder.entity(container); + } catch (Exception e) { + LOG.error("Error Applying Filters: " + e.getMessage(), e); + throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); + } + responseBuilder.cacheControl(ResponseUtil.getNoStoreCacheControl()); + return responseBuilder.build(); + + } + + /** + * {@inheritDoc} + */ + @Override + public String startJob(String jobId) { + AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + return controller.startJob(jobId); + } + + /** + * {@inheritDoc} + */ + @Override + public void killJob(String jobId) { + AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.killJob(jobId); + } + + + /** + * {@inheritDoc} + */ + @Override + public Set killAllJobs() { + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + return controller.killAllJobs(); + } + + /** + * {@inheritDoc} + */ + @Override + public void killInstance(String instanceId) { + AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.killInstance(instanceId); + } + + /** + * {@inheritDoc} + */ + @Override + public void killInstances(List instanceIds) { + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.killInstances(instanceIds); + } + + /** + * {@inheritDoc} + */ + @Override + public Set stopAllJobs() { + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + return controller.stopAllJobs(); + } + + /** + * {@inheritDoc} + */ + @Override + public void stopJob(String jobId) { + AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.stopJob(jobId); + } + + /** + * {@inheritDoc} + */ + @Override + public void stopAgent(String instanceId) { + AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.stopAgent(instanceId); + + } + + /** + * {@inheritDoc} + */ + @Override + public void stopAgents(List instanceIds) { + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.stopAgents(instanceIds); + } + + /** + * {@inheritDoc} + */ + @Override + public void pauseJob(String jobId) { + AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.pauseJob(jobId); + } + + /** + * {@inheritDoc} + */ + @Override + public void pauseAgent(String instanceId) { + AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.pauseAgent(instanceId); + } + + /** + * {@inheritDoc} + */ + @Override + public void pauseAgents(List instanceIds) { + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.pauseAgents(instanceIds); + } + + /** + * {@inheritDoc} + */ + @Override + public void restartJob(String jobId) { + AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.restartJob(jobId); + } + + /** + * {@inheritDoc} + */ + @Override + public void restartAgent(String instanceId) { + AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.restartAgent(instanceId); + } + + /** + * {@inheritDoc} + */ + @Override + public void restartAgents(List instanceIds) { + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.restartAgents(instanceIds); + } + + /** + * {@inheritDoc} + */ + @Override + public void pauseRampInstance(String instanceId) { + AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.pauseRampInstance(instanceId); + } + + /** + * {@inheritDoc} + */ + @Override + public void pauseRampJob(String jobId) { + AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.pauseRampJob(jobId); + } + + /** + * {@inheritDoc} + */ + @Override + public void pauseRampInstances(List instanceIds) { + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.pauseRampInstances(instanceIds); + } + + /** + * {@inheritDoc} + */ + @Override + public void resumeRampInstance(String instanceId) { + AWSXRay.getCurrentSegment().putAnnotation("instanceId", instanceId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.resumeRampInstance(instanceId); + } + + /** + * {@inheritDoc} + */ + @Override + public void resumeRampJob(String jobId) { + AWSXRay.getCurrentSegment().putAnnotation("jobId", jobId); + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.resumeRampJob(jobId); + } + + /** + * {@inheritDoc} + */ + @Override + public void resumeRampInstances(List instanceIds) { + JobController controller = new ServletInjector().getManagedBean( + servletContext, JobController.class); + controller.resumeRampInstances(instanceIds); + } + + /** + * {@inheritDoc} + */ + @Override + public String getCostingForDates(String startDate, String endDate) { + // AWSCostRetriever retriever = new AWSCostRetriever(); + // Calendar start = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // Calendar end = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + // start.setTime(parseDateString(startDate)); + // end.setTime(parseDateString(endDate)); + // ServiceUsage usage = retriever.getCustomReport(start, end); + // UsageCalculator calc = new UsageCalculator(usage); + // return AwsUtil.generateReport(calc); + throw new RuntimeException("Not implemented"); + } + + /** + * {@inheritDoc} + */ + @Override + public String getCostingForDates(String timePeriod) { + throw new RuntimeException("Not implemented"); + // AWSCostRetriever retriever = new AWSCostRetriever(); + // ServiceUsage usage = retriever.getPreDefinedReport(TimePeriodSelectChoice.valueOf(timePeriod)); + // UsageCalculator calc = new UsageCalculator(usage); + // return AwsUtil.generateReport(calc); + } + +} diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CostingCache.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CostingCache.java new file mode 100644 index 000000000..5e1d5a843 --- /dev/null +++ b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/CostingCache.java @@ -0,0 +1,102 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.service.impl.v1.cloud; + +/* + * #%L + * Cloud Rest Service + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import javax.enterprise.context.ApplicationScoped; + +/** + * CostingCache + * + * @author dangleton + * + */ +@ApplicationScoped +public class CostingCache { + + // private Map cache = new HashMap(); + // + // public ServiceUsage getUsageForType(TimePeriodSelectChoice timePeriod) { + // ServiceUsage ret = null; + // return ret; + // } + // + // private static class UsageKey { + // private String timePeriod; + // private Calendar startDate; + // private Calendar endDate; + // /** + // * @param timePeriod + // * @param startDate + // * @param endDate + // */ + // private UsageKey(String timePeriod, Calendar startDate, Calendar endDate) { + // super(); + // this.timePeriod = timePeriod; + // this.startDate = startDate; + // this.endDate = endDate; + // } + // + // + // /** + // * {@inheritDoc} + // */ + // @Override + // public boolean equals(Object obj) { + // if (!(obj instanceof UsageKey)) { + // return false; + // } + // UsageKey o = (UsageKey) obj; + // return new EqualsBuilder().append(o.timePeriod, timePeriod).append(o.startDate, startDate).append(o.endDate, + // endDate).isEquals(); + // } + // + // /** + // * {@inheritDoc} + // */ + // @Override + // public int hashCode() { + // return new HashCodeBuilder(21, 55).append(timePeriod).append(startDate).append(endDate).toHashCode(); + // } + // } + // + // private static class UsageValue { + // private static final long VALID_FOR_TIME = 1000 * 60 * 60 * 12;//twelve hours + // private ServiceUsage usage; + // private String timePeriod; + // private long timestamp = System.currentTimeMillis(); + // + // /** + // * @param usage + // */ + // private UsageValue(ServiceUsage usage, String timePeriod) { + // super(); + // this.usage = usage; + // } + // + // /** + // * @return the usage + // */ + // public ServiceUsage getUsage() { + // return usage; + // } + // + // public boolean isValid() { + // long currTime = System.currentTimeMillis(); + // return currTime < timestamp + VALID_FOR_TIME; + // } + // } +} diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobController.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobController.java new file mode 100644 index 000000000..a373c0d3b --- /dev/null +++ b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobController.java @@ -0,0 +1,336 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.service.impl.v1.cloud; + +/* + * #%L + * Cloud Rest Service + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.enterprise.context.RequestScoped; +import javax.enterprise.event.Event; +import javax.inject.Inject; +import javax.inject.Named; + +import com.amazonaws.xray.AWSXRay; +import com.intuit.tank.vm.vmManager.VMTracker; +import com.intuit.tank.vm.vmManager.models.CloudVmStatus; +import com.intuit.tank.vm.vmManager.models.CloudVmStatusContainer; +import com.intuit.tank.vm.vmManager.models.VMStatus; +import com.intuit.tank.dao.JobInstanceDao; +import com.intuit.tank.dao.WorkloadDao; +import com.intuit.tank.dao.util.ProjectDaoUtil; +import com.intuit.tank.harness.data.HDWorkload; +import com.intuit.tank.perfManager.workLoads.JobManager; +import com.intuit.tank.project.JobInstance; +import com.intuit.tank.project.Workload; +import com.intuit.tank.transform.scriptGenerator.ConverterUtil; +import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; +import com.intuit.tank.vm.api.enumerated.JobQueueStatus; +import com.intuit.tank.vm.api.enumerated.JobStatus; +import com.intuit.tank.vm.api.enumerated.VMRegion; +import com.intuit.tank.vm.event.JobEvent; +import com.intuit.tank.vm.perfManager.AgentChannel; +import com.intuit.tank.vm.settings.TankConfig; +import com.intuit.tank.vmManager.environment.amazon.AmazonInstance; + +/** + * CloudServiceV1 + * + * @author dangleton + * + */ +@Named +@RequestScoped +public class JobController { + + @Inject + private VMTracker vmTracker; + + @Inject + private JobManager jobManager; + + @Inject + private AgentChannel agentChannel; + + @Inject + private Event jobEventProducer; + + @Inject + private CloudController cloudController; + + /** + * {@inheritDoc} + */ + public String startJob(String jobId) { + AWSXRay.beginSubsegment("Start.Job." + jobId); + JobInstanceDao jobInstanceDao = new JobInstanceDao(); + JobInstance job = jobInstanceDao.findById(Integer.valueOf(jobId)); + synchronized (jobId) { + if (job.getStatus() == JobQueueStatus.Created) {// only start if new job + // save the job + job.setStatus(JobQueueStatus.Starting); + jobInstanceDao.saveOrUpdate(job); + + ProjectDaoUtil.storeScriptFile(jobId, getScriptString(job)); + + vmTracker.removeStatusForJob(jobId); + jobManager.startJob(job.getId()); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STARTED)); + } + } + AWSXRay.endSubsegment(); + return jobId; + } + + /** + * Use the AWS SDK to terminate instances. + * If no instances can be found, set jobStatus to Completed + */ + public void killJob(String jobId, boolean fireEvent) { + List instanceIds = getInstancesForJob(jobId); + vmTracker.stopJob(jobId); + if (instanceIds.isEmpty()) { + JobInstanceDao dao = new JobInstanceDao(); + JobInstance job = dao.findById(Integer.parseInt(jobId)); + if (job != null) { + job.setStatus(JobQueueStatus.Completed); + job.setEndTime(new Date()); + dao.saveOrUpdate(job); + } + } else { + killInstances(instanceIds); + } + + if (fireEvent) { + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_KILLED)); + } + } + + /** + * {@inheritDoc} + */ + public void killJob(String jobId) { + killJob(jobId, true); + } + + /** + * {@inheritDoc} + */ + public Set killAllJobs() { + Set jobs = vmTracker.getAllJobs(); + for (CloudVmStatusContainer job : jobs) { + String jobId = job.getJobId(); + killJob(jobId, true); + } + return jobs; + } + + /** + * {@inheritDoc} + */ + public void killInstance(String instanceId) { killInstances(Collections.singletonList(instanceId)); } + + /** + * {@inheritDoc} + */ + public void killInstances(List instanceIds) { + agentChannel.killAgents(instanceIds); + + if (!vmTracker.isDevMode()) { + for (VMRegion region : new TankConfig().getVmManagerConfig().getRegions()) { + AmazonInstance amzInstance = new AmazonInstance(region); + amzInstance.killInstances(instanceIds); + } + } + String jobId = null; + for (String instanceId : instanceIds) { + CloudVmStatus status = new CloudVmStatus(vmTracker.getStatus(instanceId)); + status.setCurrentUsers(0); + status.setEndTime(new Date()); + status.setJobStatus(JobStatus.Completed); + status.setVmStatus(VMStatus.terminated); + vmTracker.setStatus(status); + jobId = status.getJobId(); + } + if (jobId != null) { + cloudController.checkJobStatus(jobId); + } + } + + /** + * {@inheritDoc} + */ + public Set stopAllJobs() { + Set jobs = vmTracker.getAllJobs(); + for (CloudVmStatusContainer job : jobs) { + String jobId = (job).getJobId(); + List instanceIds = getInstancesForJob(jobId); + vmTracker.stopJob(jobId); + stopAgents(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STOPPED)); + } + return jobs; + } + + /** + * {@inheritDoc} + */ + public void stopJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + vmTracker.stopJob(jobId); + stopAgents(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_STOPPED)); + } + + /** + * {@inheritDoc} + */ + public void stopAgent(String instanceId) { + stopAgents(Collections.singletonList(instanceId)); + + } + + /** + * {@inheritDoc} + */ + public void stopAgents(List instanceIds) { + agentChannel.stopAgents(instanceIds); + } + + /** + * {@inheritDoc} + */ + public void pauseJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + pauseAgents(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_PAUSED)); + } + + /** + * {@inheritDoc} + */ + public void pauseAgent(String instanceId) { + pauseAgents(Collections.singletonList(instanceId)); + } + + /** + * {@inheritDoc} + */ + public void pauseAgents(List instanceIds) { + agentChannel.pauseAgents(instanceIds); + } + + /** + * {@inheritDoc} + */ + public void restartJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + restartAgents(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.JOB_RESUMED)); + } + + /** + * {@inheritDoc} + */ + public void restartAgent(String instanceId) { + restartAgents(Collections.singletonList(instanceId)); + } + + /** + * {@inheritDoc} + */ + public void restartAgents(List instanceIds) { + agentChannel.restartAgents(instanceIds); + } + + /** + * {@inheritDoc} + */ + public void pauseRampInstance(String instanceId) { + pauseRampInstances(Collections.singletonList(instanceId)); + } + + /** + * {@inheritDoc} + */ + public void pauseRampJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + pauseRampInstances(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.RAMP_PAUSED)); + } + + /** + * {@inheritDoc} + */ + public void pauseRampInstances(List instanceIds) { + agentChannel.pauseRamp(instanceIds); + } + + /** + * {@inheritDoc} + */ + public void resumeRampInstance(String instanceId) { + resumeRampInstances(Collections.singletonList(instanceId)); + } + + /** + * {@inheritDoc} + */ + public void resumeRampJob(String jobId) { + List instanceIds = getInstancesForJob(jobId); + resumeRampInstances(instanceIds); + jobEventProducer.fire(new JobEvent(jobId, "", JobLifecycleEvent.RAMP_RESUMED)); + } + + /** + * {@inheritDoc} + */ + public void resumeRampInstances(List instanceIds) { + agentChannel.resumeRamp(instanceIds); + } + + /** + * @param jobId + * @return + */ + private List getInstancesForJob(String jobId) { + List instanceIds = new ArrayList(); + CloudVmStatusContainer statuses = vmTracker.getVmStatusForJob(jobId); + if (statuses != null) { + instanceIds = statuses.getStatuses().stream().map(CloudVmStatus::getInstanceId).collect(Collectors.toList()); + } + return instanceIds; + } + + /** + * @param job + * @return + */ + public static String getScriptString(JobInstance job) { + WorkloadDao dao = new WorkloadDao(); + Workload workload = dao.findById(job.getWorkloadId()); + workload.getTestPlans(); + dao.loadScriptsForWorkload(workload); + HDWorkload hdWorkload = ConverterUtil.convertWorkload(workload, job); + return ConverterUtil.getWorkloadXML(hdWorkload); + } + +} diff --git a/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobListener.java b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobListener.java new file mode 100644 index 000000000..f87428bbb --- /dev/null +++ b/rest/service/cloud/src/main/java/com/intuit/tank/service/impl/v1/cloud/JobListener.java @@ -0,0 +1,56 @@ +/** + * Copyright 2011 Intuit Inc. All Rights Reserved + */ +package com.intuit.tank.service.impl.v1.cloud; + +/* + * #%L + * Cloud Rest Service + * %% + * Copyright (C) 2011 - 2015 Intuit Inc. + * %% + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * #L% + */ + +import java.io.Serializable; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent; +import com.intuit.tank.vm.event.JobEvent; + +/** + * JobListener + * + * @author dangleton + * + */ +@Named +@ApplicationScoped +public class JobListener implements Serializable { + + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LogManager.getLogger(JobListener.class); + + @Inject + private Instance controllerSource; + + public void observerJobKillRequest(@Observes JobEvent request) { + LOG.info("Got Job Event: " + request); + if (request.getEvent() == JobLifecycleEvent.JOB_ABORTED) { + controllerSource.get().killJob(request.getJobId(), false); + } + } +} diff --git a/rest/service/cloud/src/main/resources/META-INF/beans.xml b/rest/service/cloud/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..0da69df74 --- /dev/null +++ b/rest/service/cloud/src/main/resources/META-INF/beans.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/rest/service/cloud/src/test/java/com/intuit/tank/service/impl/v1/cloud/CloudSercieV1Test.java b/rest/service/cloud/src/test/java/com/intuit/tank/service/impl/v1/cloud/CloudSercieV1Test.java new file mode 100644 index 000000000..22d3a5c4f --- /dev/null +++ b/rest/service/cloud/src/test/java/com/intuit/tank/service/impl/v1/cloud/CloudSercieV1Test.java @@ -0,0 +1,58 @@ +package com.intuit.tank.service.impl.v1.cloud; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.MockitoAnnotations; + +import static org.junit.jupiter.api.Assertions.*; + +public class CloudSercieV1Test { + + @InjectMocks + CloudServiceV1 cloudServiceV1; + + private AutoCloseable closeable; + + @BeforeEach + void initService() { + closeable = MockitoAnnotations.openMocks(this); + } + + @AfterEach + void closeService() throws Exception { + closeable.close(); + } + + @Test + public void testPing() { + assertEquals("PONG CloudServiceV1", cloudServiceV1.ping()); + } + + @Test + public void testUserIdFromRangeEmpty() { + assertEquals("0",cloudServiceV1.userIdFromRange("0", 0, 0)); + } + + @Test + public void testUserIdFromRange() { + String result = cloudServiceV1.userIdFromRange("0", 0, 10); + assertTrue(Integer.parseInt(result) >= 0 && Integer.parseInt(result) <= 10); + } + + @Test + public void testCostingForDates_1() { + assertThrows(RuntimeException.class, () -> { + cloudServiceV1.getCostingForDates("", ""); + }); + } + + @Test + public void testCostingForDates_2() { + assertThrows(RuntimeException.class, () -> { + cloudServiceV1.getCostingForDates(""); + }); + } + +} diff --git a/rest/service/pom.xml b/rest/service/pom.xml index ee12d4265..c3a85bed5 100644 --- a/rest/service/pom.xml +++ b/rest/service/pom.xml @@ -16,6 +16,7 @@ automation + cloud user datafile script diff --git a/rest/service/reporting/pom.xml b/rest/service/reporting/pom.xml index 90661c946..2cbfcf600 100644 --- a/rest/service/reporting/pom.xml +++ b/rest/service/reporting/pom.xml @@ -15,6 +15,13 @@ Reporting Rest Service Implementation + + + ${project.groupId} + cloud-api + ${project.version} + + ${project.groupId} report-api diff --git a/tank_vmManager/pom.xml b/tank_vmManager/pom.xml index 53195ce61..5592d2a4d 100644 --- a/tank_vmManager/pom.xml +++ b/tank_vmManager/pom.xml @@ -34,6 +34,12 @@ ${project.version} + + ${project.groupId} + cloud-api + ${project.version} + + ${project.groupId} data-access diff --git a/tools/agent_debugger/pom.xml b/tools/agent_debugger/pom.xml index 49bfe8278..32d314d10 100755 --- a/tools/agent_debugger/pom.xml +++ b/tools/agent_debugger/pom.xml @@ -22,6 +22,12 @@ ${project.version} + + ${project.groupId} + tank-api + ${project.version} + + ${project.groupId} script-client diff --git a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/ActionProducer.java b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/ActionProducer.java index 78fd3bc7f..6ba265357 100644 --- a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/ActionProducer.java +++ b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/ActionProducer.java @@ -25,11 +25,8 @@ import java.io.Writer; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; +import java.util.*; +import java.util.stream.Collectors; import javax.imageio.ImageIO; import javax.swing.AbstractAction; @@ -50,19 +47,19 @@ import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException; +import org.springframework.web.reactive.function.client.WebClientRequestException; import org.xml.sax.SAXException; -import com.intuit.tank.AgentServiceClient; -import com.intuit.tank.api.model.v1.agent.TankHttpClientDefinition; -import com.intuit.tank.api.model.v1.agent.TankHttpClientDefinitionContainer; -import com.intuit.tank.api.model.v1.datafile.DataFileDescriptor; -import com.intuit.tank.api.model.v1.project.ProjectTO; -import com.intuit.tank.api.model.v1.script.ScriptDescription; -import com.intuit.tank.api.model.v1.script.ScriptDescriptionContainer; -import com.intuit.tank.client.v1.datafile.DataFileClient; -import com.intuit.tank.client.v1.project.ProjectServiceClientV1; -import com.intuit.tank.client.v1.script.ScriptServiceClient; +import com.intuit.tank.rest.mvc.rest.clients.AgentClient; +import com.intuit.tank.rest.mvc.rest.clients.DataFileClient; +import com.intuit.tank.rest.mvc.rest.clients.ProjectClient; +import com.intuit.tank.rest.mvc.rest.clients.ScriptClient; +import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinition; +import com.intuit.tank.rest.mvc.rest.models.agent.TankHttpClientDefinitionContainer; +import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescription; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptDescriptionContainer; import com.intuit.tank.harness.data.HDWorkload; import com.intuit.tank.tools.debugger.FindReplaceDialog.DialogType; @@ -101,9 +98,9 @@ public class ActionProducer { private Map actionMap = new HashMap(); private int menuActionMods = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); private JFileChooser jFileChooser = null; - private ScriptServiceClient scriptServiceClient; - private AgentServiceClient agentServiceClient; - private ProjectServiceClientV1 projectServiceClient; + private ScriptClient scriptClient; + private AgentClient agentClient; + private ProjectClient projectClient; private DataFileClient dataFileClient; /** @@ -114,9 +111,9 @@ public class ActionProducer { public ActionProducer(AgentDebuggerFrame debuggerFrame, String serviceUrl) { super(); this.debuggerFrame = debuggerFrame; - this.scriptServiceClient = new ScriptServiceClient(serviceUrl); - this.projectServiceClient = new ProjectServiceClientV1(serviceUrl); - this.agentServiceClient = new AgentServiceClient(serviceUrl); + this.scriptClient = new ScriptClient(serviceUrl); + this.projectClient = new ProjectClient(serviceUrl); + this.agentClient = new AgentClient(serviceUrl); this.dataFileClient = new DataFileClient(serviceUrl); jFileChooser = new JFileChooser(); @@ -135,17 +132,17 @@ public boolean accept(File f) { } /** - * @return the scriptServiceClient + * @return the scriptClient */ - public ScriptServiceClient getScriptServiceClient() { - return scriptServiceClient; + public ScriptClient getScriptClient() { + return scriptClient; } /** - * @return the projectServiceClient + * @return the projectClient */ - public ProjectServiceClientV1 getProjectServiceClient() { - return projectServiceClient; + public ProjectClient getProjectClient() { + return projectClient; } /** @@ -160,10 +157,10 @@ public DataFileClient getDataFileClient() { * @param serviceUrl */ public void setServiceUrl(String serviceUrl) { - this.scriptServiceClient = new ScriptServiceClient(serviceUrl); - this.projectServiceClient = new ProjectServiceClientV1(serviceUrl); + this.scriptClient = new ScriptClient(serviceUrl); + this.projectClient = new ProjectClient(serviceUrl); this.dataFileClient = new DataFileClient(serviceUrl); - this.agentServiceClient = new AgentServiceClient(serviceUrl); + this.agentClient = new AgentClient(serviceUrl); PanelBuilder.updateServiceUrl(serviceUrl); setChoiceComboBoxOptions(debuggerFrame.getTankClientChooser()); } @@ -333,11 +330,11 @@ public void actionPerformed(ActionEvent event) { if (scriptSource.getSource() == SourceType.file) { scriptXml = FileUtils.readFileToString(new File(scriptSource.getId()), StandardCharsets.UTF_8); } else if (scriptSource.getSource() == SourceType.script) { - scriptXml = scriptServiceClient.downloadHarnessXml(Integer + scriptXml = scriptClient.downloadHarnessScript(Integer .parseInt(scriptSource .getId())); } else if (scriptSource.getSource() == SourceType.project) { - scriptXml = projectServiceClient.downloadTestScriptForProject(Integer + scriptXml = projectClient.downloadTestScriptForProject(Integer .parseInt(scriptSource.getId())); } if (scriptXml != null) { @@ -402,7 +399,7 @@ public void actionPerformed(ActionEvent event) { url = "http://" + url; } try { - new ScriptServiceClient(url).ping(); + new ScriptClient(url).ping(); setServiceUrl(url); } catch (Exception e) { showError("Cannot connect to Tank at the url " + url @@ -425,7 +422,7 @@ public void actionPerformed(ActionEvent event) { public void setChoiceComboBoxOptions(JComboBox cb) { cb.removeAllItems(); try { - TankHttpClientDefinitionContainer clientDefinitions = agentServiceClient.getClientDefinitions(); + TankHttpClientDefinitionContainer clientDefinitions = agentClient.getClients(); for(TankHttpClientDefinition def : clientDefinitions.getDefinitions()) { TankClientChoice c = new TankClientChoice(def.getName(), def.getClassName()); cb.addItem(c); @@ -434,7 +431,7 @@ public void setChoiceComboBoxOptions(JComboBox cb) { } } } catch (Exception e) { - // This is just a filler for the UI before you select a tank instance to import from. + // This is just a filler for the UI before you select a tank instance to import from. cb.addItem(new TankClientChoice("Apache HttpClient 3.1", "com.intuit.tank.httpclient3.TankHttpClient3")); cb.addItem(new TankClientChoice("Apache HttpClient 4.5", "com.intuit.tank.httpclient4.TankHttpClient4")); cb.addItem(new TankClientChoice("Apache HttpClient 5", "com.intuit.tank.httpclient5.TankHttpClient5")); @@ -484,7 +481,7 @@ public Action getOpenScriptAction() { @Override public void actionPerformed(ActionEvent e) { try { - ScriptDescriptionContainer scriptDescriptions = scriptServiceClient.getScriptDescriptions(); + ScriptDescriptionContainer scriptDescriptions = scriptClient.getScripts(); List scripts = scriptDescriptions.getScripts(); scripts.sort((ScriptDescription o1, ScriptDescription o2) -> o2.getCreated().compareTo(o1.getCreated())); @@ -499,7 +496,7 @@ public void actionPerformed(ActionEvent e) { // get script in thread new Thread( () -> { try { - String scriptXml = scriptServiceClient.downloadHarnessXml(scriptSelected + String scriptXml = scriptClient.downloadHarnessScript(scriptSelected .getId()); setFromString(scriptXml); debuggerFrame.setCurrentTitle("Selected Script: " + scriptSelected.getName()); @@ -513,8 +510,11 @@ public void actionPerformed(ActionEvent e) { } }).start(); } - } catch (Exception e1) { - showError("Error downloading scripts: " + e1); + } catch (WebClientRequestException e1) { + showError("Error: Empty or Invalid Tank URL"); + LOG.error("Error returning response from ScriptClient: Empty or Invalid Tank URL"); + } catch (Exception e2) { + showError("Error downloading scripts: " + e2); } } }; @@ -537,7 +537,7 @@ public Action getSelectDataFileAction() { @Override public void actionPerformed(ActionEvent e) { try { - List dataFiles = dataFileClient.getDataFiles(); + List dataFiles = dataFileClient.getDatafiles().getDataFiles(); dataFiles.sort((DataFileDescriptor o1, DataFileDescriptor o2) -> o2.getName().compareTo(o1.getName())); SelectDialog selectDialog = new SelectDialog( @@ -548,8 +548,11 @@ public void actionPerformed(ActionEvent e) { if (!selectedObjects.isEmpty()) { debuggerFrame.setDataFiles(selectedObjects); } - } catch (Exception e1) { - showError("Error downloading datafiles: " + e1); + } catch (WebClientRequestException e1) { + showError("Error: Empty or Invalid Tank URL"); + LOG.error("Error returning response from DataFileClient: Empty or Invalid Tank URL"); + } catch (Exception e2) { + showError("Error downloading datafiles: " + e2); } } }; @@ -597,19 +600,21 @@ public Action getOpenProjectAction() { @Override public void actionPerformed(ActionEvent e) { try { - List projects = projectServiceClient.getProjects(); - Collections.reverse(projects); - SelectDialog selectDialog = new SelectDialog(debuggerFrame, - projects, "project"); + Map projectMap = projectClient.getProjectNames().entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); + List projectNames = new ArrayList<>(projectMap.keySet()); + SelectDialog selectDialog = new SelectDialog(debuggerFrame, + projectNames, "project"); selectDialog.setVisible(true); - final ProjectTO selected = selectDialog.getSelectedObject(); + final String projectName = selectDialog.getSelectedObject(); + String projectId = String.valueOf(projectMap.get(projectName)); + ProjectTO selected = projectClient.getProject(Integer.parseInt(projectId)); if (selected != null) { debuggerFrame.startWaiting(); setFromString(null); // get script in thread new Thread( () -> { try { - String scriptXml = projectServiceClient.downloadTestScriptForProject(selected + String scriptXml = projectClient.downloadTestScriptForProject(selected .getId()); debuggerFrame.setDataFromProject(selected); setFromString(scriptXml); @@ -626,9 +631,9 @@ public void actionPerformed(ActionEvent e) { } }).start(); } - } catch (MessageBodyProviderNotFoundException e1) { - showError("Error viewing the projects response: " + e1); - LOG.error("Error viewing response from ProjectService.METHOD_PROJECT_SCRIPT_DOWNLOAD", e1); + } catch (WebClientRequestException e1) { + showError("Error: Empty or Invalid Tank URL"); + LOG.error("Error returning response from ProjectClient: Empty or Invalid Tank URL"); } catch (Exception e2) { showError("Error downloading projects: " + e2); } diff --git a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/AgentDebuggerFrame.java b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/AgentDebuggerFrame.java index 1bcb1ff67..e31788a47 100644 --- a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/AgentDebuggerFrame.java +++ b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/AgentDebuggerFrame.java @@ -29,6 +29,8 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -48,10 +50,10 @@ import org.fife.ui.rtextarea.GutterIconInfo; import org.fife.ui.rtextarea.RTextScrollPane; -import com.intuit.tank.api.model.v1.datafile.DataFileDescriptor; -import com.intuit.tank.api.model.v1.project.KeyPair; -import com.intuit.tank.api.model.v1.project.ProjectTO; -import com.intuit.tank.client.v1.datafile.DataFileClient; +import com.intuit.tank.rest.mvc.rest.models.datafiles.DataFileDescriptor; +import com.intuit.tank.rest.mvc.rest.models.projects.KeyPair; +import com.intuit.tank.rest.mvc.rest.models.projects.ProjectTO; +import com.intuit.tank.rest.mvc.rest.clients.DataFileClient; import com.intuit.tank.harness.APITestHarness; import com.intuit.tank.harness.TestPlanSingleton; import com.intuit.tank.harness.data.HDScript; @@ -789,7 +791,7 @@ private void downloadDataFiles() { if (!datafileList.isEmpty()) { DataFileClient client = debuggerActions.getDataFileClient(); for (Integer id : datafileList) { - DataFileDescriptor dataFile = client.getDataFile(id); + DataFileDescriptor dataFile = client.getDatafile(id); if (dataFile != null) { saveDataFile(client, dataFile, datafileList.size() == 1); } @@ -801,7 +803,7 @@ private void saveDataFile(DataFileClient client, DataFileDescriptor dataFileDesc File dataFile = new File(workingDir, dataFileDescriptor.getName()); LOG.info("writing file " + dataFileDescriptor.getName() + " to " + dataFile.getAbsolutePath()); try ( FileOutputStream fos = new FileOutputStream(dataFile); - InputStream is = client.getDataFileDataStream(dataFileDescriptor.getId()) ) { + InputStream is = IOUtils.toInputStream(client.getDatafileContent(dataFileDescriptor.getId()), StandardCharsets.UTF_8) ) { IOUtils.copy(is, fos); if (isDefault && !dataFileDescriptor.getName().equals(TankConstants.DEFAULT_CSV_FILE_NAME)) { File defaultFile = new File(workingDir, TankConstants.DEFAULT_CSV_FILE_NAME); diff --git a/tools/script_filter/pom.xml b/tools/script_filter/pom.xml index 923e2a530..4d9411576 100755 --- a/tools/script_filter/pom.xml +++ b/tools/script_filter/pom.xml @@ -24,7 +24,7 @@ ${project.groupId} - script-client + tank-api ${project.version} diff --git a/tools/script_filter/src/main/java/com/intuit/tank/tools/script/ScriptFilterRunner.java b/tools/script_filter/src/main/java/com/intuit/tank/tools/script/ScriptFilterRunner.java index dc3cc1141..1f6745cca 100644 --- a/tools/script_filter/src/main/java/com/intuit/tank/tools/script/ScriptFilterRunner.java +++ b/tools/script_filter/src/main/java/com/intuit/tank/tools/script/ScriptFilterRunner.java @@ -55,9 +55,9 @@ import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import com.intuit.tank.api.model.v1.script.ExternalScriptTO; -import com.intuit.tank.api.model.v1.script.ScriptTO; -import com.intuit.tank.client.v1.script.ScriptServiceClient; +import com.intuit.tank.rest.mvc.rest.models.scripts.ExternalScriptTO; +import com.intuit.tank.rest.mvc.rest.models.scripts.ScriptTO; +import com.intuit.tank.rest.mvc.rest.clients.ScriptClient; import com.intuit.tank.tools.script.ScriptRunner; /** @@ -86,7 +86,7 @@ public class ScriptFilterRunner extends JFrame { private JButton showXmlBT; private JButton saveBT; private JLabel localLB; - private ScriptServiceClient scriptServiceClient; + private ScriptClient scriptClient; private ExternalScriptTO currentExternalScript; private JFileChooser loadChooser; private boolean local = true; @@ -110,7 +110,7 @@ public void windowClosed(WindowEvent e) { } } }); - scriptServiceClient = new ScriptServiceClient(serviceUrl); + scriptClient = new ScriptClient(serviceUrl); Component topPanel = createTopPanel(); Component bottomPanel = createBottomPanel(); @@ -327,8 +327,8 @@ protected void loadScript() { } } else { - selectScript(new SelectDialog(ScriptFilterRunner.this, scriptServiceClient - .getExternalScripts())); + selectScript(new SelectDialog(ScriptFilterRunner.this, scriptClient + .getExternalScripts().getScripts())); } @@ -354,7 +354,7 @@ protected void storeScript(boolean saveAs) { + language.getDefaultExtension()); } currentExternalScript.setScript(scriptEditorTA.getText()); - currentExternalScript = scriptServiceClient.saveOrUpdateExternalScript(currentExternalScript); + currentExternalScript = scriptClient.createExternalScript(currentExternalScript); } /** diff --git a/web/web_ui/src/main/webapp/META-INF/context.xml b/web/web_ui/src/main/webapp/META-INF/context.xml index 6517d08d0..2fb659b00 100644 --- a/web/web_ui/src/main/webapp/META-INF/context.xml +++ b/web/web_ui/src/main/webapp/META-INF/context.xml @@ -5,5 +5,18 @@ auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> + From 834f2186c75ff0384f1d19c43bf25ced2722ac52 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 09:29:26 -0700 Subject: [PATCH 36/73] reverting local files --- proxy-parent/owasp-proxy/pom.xml | 5 ----- .../intuit/tank/rest/mvc/TankAPIApplication.java | 11 +++++++++-- web/web_ui/src/main/webapp/META-INF/context.xml | 13 ------------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml index 42064e1c8..3299f5e5f 100755 --- a/proxy-parent/owasp-proxy/pom.xml +++ b/proxy-parent/owasp-proxy/pom.xml @@ -96,11 +96,6 @@ 0.1.2 - - org.springframework - spring-dao - 2.0.8 - diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java index 231a2e8f5..6a3d3d1aa 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/TankAPIApplication.java @@ -7,16 +7,23 @@ */ package com.intuit.tank.rest.mvc; +import com.intuit.tank.rest.mvc.rest.cloud.JobEventSender; +import com.intuit.tank.rest.mvc.rest.cloud.JobEventListener; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.servers.Server; import org.springframework.boot.SpringApplication; +import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.FilterType; -@OpenAPIDefinition(servers = {@Server(url = "/tank_war", description = "Default Server URL")}) -@SpringBootApplication +@OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server URL")}) +@SpringBootApplication(proxyBeanMethods = false) +@ComponentScan(basePackages = "com.intuit.tank.rest.mvc", excludeFilters = { + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {JobEventSender.class, JobEventListener.class}) +}) public class TankAPIApplication extends SpringBootServletInitializer { public static ConfigurableApplicationContext run(String[] args) { return SpringApplication.run(TankAPIApplication.class, args); diff --git a/web/web_ui/src/main/webapp/META-INF/context.xml b/web/web_ui/src/main/webapp/META-INF/context.xml index 2fb659b00..6517d08d0 100644 --- a/web/web_ui/src/main/webapp/META-INF/context.xml +++ b/web/web_ui/src/main/webapp/META-INF/context.xml @@ -5,18 +5,5 @@ auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" /> - From d089dceac0688e80f95375e6f7608e76b20aa7d2 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 09:42:31 -0700 Subject: [PATCH 37/73] updating package names --- .../java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java | 2 +- .../intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java | 2 +- .../main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java | 2 +- .../intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java | 2 +- .../java/com/intuit/tank/api/model/v1/cloud/UserDetail.java | 2 +- .../main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java | 2 +- .../com/intuit/tank/api/model/v1/cloud/ValidationStatus.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java index f8ff1deb7..0433d57d9 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatus.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.vm.vmManager.models; +package com.intuit.tank.api.model.v1.cloud; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java index adee83973..8fc265b64 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/CloudVmStatusContainer.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.vm.vmManager.models; +package com.intuit.tank.api.model.v1.cloud; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java index 2d0bc30a5..6a3d5bec6 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/Namespace.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.vm.vmManager.models; +package com.intuit.tank.api.model.v1.cloud; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java index df2f75899..478c722aa 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ProjectStatusContainer.java @@ -1,7 +1,7 @@ /** * Copyright 2011 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.vm.vmManager.models; +package com.intuit.tank.api.model.v1.cloud; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java index 3704c0a3c..257f1c746 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/UserDetail.java @@ -1,4 +1,4 @@ -package com.intuit.tank.vm.vmManager.models; +package com.intuit.tank.api.model.v1.cloud; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java index 6c709b854..298b51980 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/VMStatus.java @@ -1,4 +1,4 @@ -package com.intuit.tank.vm.vmManager.models; +package com.intuit.tank.api.model.v1.cloud; /* * #%L diff --git a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java index 395c6eeeb..908497141 100644 --- a/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java +++ b/rest/api/cloud/src/main/java/com/intuit/tank/api/model/v1/cloud/ValidationStatus.java @@ -1,7 +1,7 @@ /** * Copyright 2013 Intuit Inc. All Rights Reserved */ -package com.intuit.tank.vm.vmManager.models; +package com.intuit.tank.api.model.v1.cloud; /* * #%L From ea8d78a65de323a2d94122f69586973249e189d9 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Fri, 9 Jun 2023 12:29:50 -0700 Subject: [PATCH 38/73] update UI refs to /v2 path --- .../src/main/java/com/intuit/tank/admin/LogViewer.java | 2 +- web/web_ui/src/main/webapp/agents/index.xhtml | 4 ++-- web/web_ui/src/main/webapp/projects/projectjobqueue.xhtml | 4 ++-- web/web_ui/src/main/webapp/projects/workloadScripts.xhtml | 2 +- web/web_ui/src/main/webapp/scripts/index.xhtml | 4 ++-- web/web_ui/src/main/webapp/scripts/script-edit-view.xhtml | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/web/web_support/src/main/java/com/intuit/tank/admin/LogViewer.java b/web/web_support/src/main/java/com/intuit/tank/admin/LogViewer.java index 4272c61b3..e5be4d133 100644 --- a/web/web_support/src/main/java/com/intuit/tank/admin/LogViewer.java +++ b/web/web_support/src/main/java/com/intuit/tank/admin/LogViewer.java @@ -81,7 +81,7 @@ public String getLogFileUrl() { if (StringUtils.isNotBlank(currentLogFile)) { String contextPath = FacesContext.getCurrentInstance().getExternalContext() .getRequestContextPath(); - return getContextRoot(contextPath) + "api/v2/logs" + File.separator + return getContextRoot(contextPath) + "v2/logs" + File.separator + URLEncoder.encode(currentLogFile, StandardCharsets.UTF_8); } return null; diff --git a/web/web_ui/src/main/webapp/agents/index.xhtml b/web/web_ui/src/main/webapp/agents/index.xhtml index 0e4d807e9..f5b7f0ff9 100644 --- a/web/web_ui/src/main/webapp/agents/index.xhtml +++ b/web/web_ui/src/main/webapp/agents/index.xhtml @@ -198,13 +198,13 @@
+ value="#{request.contextPath}/v2/jobs/download/#{node.id}"> + value="#{request.contextPath}/v2/projects/download/#{node.id}"> diff --git a/web/web_ui/src/main/webapp/projects/projectjobqueue.xhtml b/web/web_ui/src/main/webapp/projects/projectjobqueue.xhtml index b5d5d39b4..46de404e6 100644 --- a/web/web_ui/src/main/webapp/projects/projectjobqueue.xhtml +++ b/web/web_ui/src/main/webapp/projects/projectjobqueue.xhtml @@ -205,13 +205,13 @@
+ value="#{request.contextPath}/v2/jobs/download/#{node.id}"> + value="#{request.contextPath}/v2/projects/download/#{node.id}"> diff --git a/web/web_ui/src/main/webapp/projects/workloadScripts.xhtml b/web/web_ui/src/main/webapp/projects/workloadScripts.xhtml index 03c173a62..35e79280d 100644 --- a/web/web_ui/src/main/webapp/projects/workloadScripts.xhtml +++ b/web/web_ui/src/main/webapp/projects/workloadScripts.xhtml @@ -14,7 +14,7 @@
diff --git a/web/web_ui/src/main/webapp/scripts/index.xhtml b/web/web_ui/src/main/webapp/scripts/index.xhtml index 3ae03d116..c58a82012 100644 --- a/web/web_ui/src/main/webapp/scripts/index.xhtml +++ b/web/web_ui/src/main/webapp/scripts/index.xhtml @@ -208,14 +208,14 @@ + onclick="location.href='#{request.contextPath}/v2/scripts/harness/download/#{selectable.entity.id}'"> + onclick="location.href='#{request.contextPath}/v2/scripts/download/#{selectable.entity.id}'"> diff --git a/web/web_ui/src/main/webapp/scripts/script-edit-view.xhtml b/web/web_ui/src/main/webapp/scripts/script-edit-view.xhtml index f121cb091..45be8591d 100644 --- a/web/web_ui/src/main/webapp/scripts/script-edit-view.xhtml +++ b/web/web_ui/src/main/webapp/scripts/script-edit-view.xhtml @@ -56,12 +56,12 @@ styleClass="icon-button h-space" /> From ee46bcc8a659a116b90b0bfd898e925dd3f538f2 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Sun, 11 Jun 2023 00:40:26 -0700 Subject: [PATCH 39/73] banner fixed to stay closed each session --- .../intuit/tank/ProjectDescriptionBean.java | 16 +++++++++++++--- .../intuit/tank/auth/TankAuthenticator.java | 2 ++ .../tank/filter/FilterGroupCreationBean.java | 18 ++++++++++++++++++ .../intuit/tank/project/DataFileBrowser.java | 11 +++++++++++ .../intuit/tank/project/JobTreeTableBean.java | 16 ++++++++++++++++ .../com/intuit/tank/script/ScriptBean.java | 12 ++++++++++++ web/web_ui/src/main/webapp/agents/index.xhtml | 17 +++++++++++++++++ .../src/main/webapp/datafiles/index.xhtml | 14 ++++++++++++++ web/web_ui/src/main/webapp/filters/index.xhtml | 18 +++++++++++++++++- .../src/main/webapp/projects/index.xhtml | 15 +++++++++++++++ web/web_ui/src/main/webapp/scripts/index.xhtml | 15 +++++++++++++++ 11 files changed, 150 insertions(+), 4 deletions(-) diff --git a/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java b/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java index fe99bc4a1..ae8b0c74a 100644 --- a/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/ProjectDescriptionBean.java @@ -18,6 +18,9 @@ import javax.annotation.PostConstruct; import javax.enterprise.event.Event; +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; +import javax.faces.event.AjaxBehaviorEvent; import javax.faces.model.SelectItem; import javax.faces.view.ViewScoped; import javax.inject.Inject; @@ -66,11 +69,18 @@ public class ProjectDescriptionBean extends SelectableBean implements S @PostConstruct public void init() { + boolean showMessage = (boolean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("showMessage"); + if(showMessage) { + FacesContext.getCurrentInstance().addMessage("formId:banner", new FacesMessage(FacesMessage.SEVERITY_WARN, "Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + + "download the newest version of Tank tools under the 'Tools' tab. Please refer to the Tank V2 API documentation " + + "under 'Help' for more details on the new API features.", null)); + } tablePrefs = new TablePreferences(userPrefs.getPreferences().getProjectTableColumns()); tablePrefs.registerListener(userPrefs); - messages.warn("Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + - "download the newest version of Tank tools under the 'Tools' tab. Please refer to the Tank V2 API documentation " + - "under 'Help' for more details on the new features."); + } + + public void closeMessage(){ + FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("showMessage", false); } public void deleteSelectedProject() { diff --git a/web/web_support/src/main/java/com/intuit/tank/auth/TankAuthenticator.java b/web/web_support/src/main/java/com/intuit/tank/auth/TankAuthenticator.java index bbe21d0a7..68065e138 100644 --- a/web/web_support/src/main/java/com/intuit/tank/auth/TankAuthenticator.java +++ b/web/web_support/src/main/java/com/intuit/tank/auth/TankAuthenticator.java @@ -78,6 +78,8 @@ public void login() throws IOException { break; case SUCCESS: messages.info("You're signed in as " + username); + FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("showMessage", true); + FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("intialPost", true); FacesContext.getCurrentInstance().getExternalContext().redirect( FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath() + "/projects/index.jsf"); break; diff --git a/web/web_support/src/main/java/com/intuit/tank/filter/FilterGroupCreationBean.java b/web/web_support/src/main/java/com/intuit/tank/filter/FilterGroupCreationBean.java index bfa70cbd2..d8cf05a6f 100644 --- a/web/web_support/src/main/java/com/intuit/tank/filter/FilterGroupCreationBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/filter/FilterGroupCreationBean.java @@ -18,12 +18,16 @@ import java.util.List; import java.util.Set; +import javax.annotation.PostConstruct; import javax.enterprise.context.Conversation; import javax.enterprise.context.ConversationScoped; +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; import javax.inject.Inject; import javax.inject.Named; import com.intuit.tank.auth.TankSecurityContext; +import com.intuit.tank.prefs.TablePreferences; import org.apache.commons.lang3.StringUtils; import com.intuit.tank.util.Messages; @@ -62,6 +66,20 @@ public class FilterGroupCreationBean extends SelectableBean implem private boolean editing; + @PostConstruct + public void init() { + boolean showMessage = (boolean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("showMessage"); + if(showMessage) { + FacesContext.getCurrentInstance().addMessage("formId:banner", new FacesMessage(FacesMessage.SEVERITY_WARN, "Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + + "download the newest version of Tank tools under the 'Tools' tab. Please refer to the Tank V2 API documentation " + + "under 'Help' for more details on the new API features.", null)); + } + } + + public void closeMessage(){ + FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("showMessage", false); + } + /** * @return the isEditing */ diff --git a/web/web_support/src/main/java/com/intuit/tank/project/DataFileBrowser.java b/web/web_support/src/main/java/com/intuit/tank/project/DataFileBrowser.java index 61181f404..31d0af779 100644 --- a/web/web_support/src/main/java/com/intuit/tank/project/DataFileBrowser.java +++ b/web/web_support/src/main/java/com/intuit/tank/project/DataFileBrowser.java @@ -22,6 +22,7 @@ import javax.annotation.PostConstruct; import javax.enterprise.event.Event; +import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import javax.faces.model.SelectItem; import javax.faces.view.ViewScoped; @@ -89,10 +90,20 @@ public class DataFileBrowser extends SelectableBean implements Seriali @PostConstruct public void init() { + boolean showMessage = (boolean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("showMessage"); + if(showMessage) { + FacesContext.getCurrentInstance().addMessage("formId:banner", new FacesMessage(FacesMessage.SEVERITY_WARN, "Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + + "download the newest version of Tank tools under the 'Tools' tab. Please refer to the Tank V2 API documentation " + + "under 'Help' for more details on the new API features.", null)); + } tablePrefs = new TablePreferences(userPrefs.getPreferences().getDatafilesTableColumns()); tablePrefs.registerListener(userPrefs); } + public void closeMessage(){ + FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("showMessage", false); + } + /** * * {@inheritDoc} diff --git a/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java b/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java index a3a1d4c51..e68259523 100644 --- a/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/project/JobTreeTableBean.java @@ -30,6 +30,8 @@ import javax.annotation.Nonnull; import javax.annotation.PostConstruct; +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; import javax.inject.Inject; import com.amazonaws.xray.AWSXRay; @@ -127,12 +129,26 @@ public abstract class JobTreeTableBean implements Serializable { private TimeZone timeZone = TimeZone.getTimeZone(DEFAULT_TIME_ZONE); private Date lastDate = null; + private boolean intialPost; // limit to posting the message once per session + @PostConstruct public void init() { + boolean showMessage = (boolean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("showMessage"); + intialPost = (boolean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("intialPost"); + if(showMessage && intialPost) { + FacesContext.getCurrentInstance().addMessage("formId:banner", new FacesMessage(FacesMessage.SEVERITY_WARN, "Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + + "download the newest version of Tank tools under the 'Tools' tab. Please refer to the Tank V2 API documentation " + + "under 'Help' for more details on the new API features.", null)); + FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("intialPost", false); + } tablePrefs = new TablePreferences(preferencesBean.getPreferences().getJobsTableColumns()); tablePrefs.registerListener(preferencesBean); } + public void closeMessage(){ + FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("showMessage", false); + } + /** * @return the user TimeZone */ diff --git a/web/web_support/src/main/java/com/intuit/tank/script/ScriptBean.java b/web/web_support/src/main/java/com/intuit/tank/script/ScriptBean.java index aa83a6ac3..86bb72c5a 100644 --- a/web/web_support/src/main/java/com/intuit/tank/script/ScriptBean.java +++ b/web/web_support/src/main/java/com/intuit/tank/script/ScriptBean.java @@ -18,6 +18,8 @@ import javax.annotation.PostConstruct; import javax.enterprise.event.Event; +import javax.faces.application.FacesMessage; +import javax.faces.context.FacesContext; import javax.faces.model.SelectItem; import javax.faces.view.ViewScoped; import javax.inject.Inject; @@ -100,12 +102,22 @@ public void setSaveAsName(String saveAsName) { @PostConstruct public void init() { + boolean showMessage = (boolean) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("showMessage"); + if(showMessage) { + FacesContext.getCurrentInstance().addMessage("formId:banner", new FacesMessage(FacesMessage.SEVERITY_WARN, "Important Update: Tank V2 API is now available! To ensure compatibility with the updated API, " + + "download the newest version of Tank tools under the 'Tools' tab. Please refer to the Tank V2 API documentation " + + "under 'Help' for more details on the new API features.", null)); + } tablePrefs = new TablePreferences(userPrefs.getPreferences().getScriptsTableColumns()); stepTablePrefs = new TablePreferences(userPrefs.getPreferences().getScriptStepTableColumns()); tablePrefs.registerListener(userPrefs); } + public void closeMessage(){ + FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("showMessage", false); + } + /** * @return the stepTablePrefs */ diff --git a/web/web_ui/src/main/webapp/agents/index.xhtml b/web/web_ui/src/main/webapp/agents/index.xhtml index f5b7f0ff9..76c10a9de 100644 --- a/web/web_ui/src/main/webapp/agents/index.xhtml +++ b/web/web_ui/src/main/webapp/agents/index.xhtml @@ -49,6 +49,23 @@
+ + + + + diff --git a/web/web_ui/src/main/webapp/datafiles/index.xhtml b/web/web_ui/src/main/webapp/datafiles/index.xhtml index 1d527910f..28a819627 100644 --- a/web/web_ui/src/main/webapp/datafiles/index.xhtml +++ b/web/web_ui/src/main/webapp/datafiles/index.xhtml @@ -35,6 +35,20 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
+ + + + diff --git a/web/web_ui/src/main/webapp/filters/index.xhtml b/web/web_ui/src/main/webapp/filters/index.xhtml index 44569d6c3..59e57c4c0 100644 --- a/web/web_ui/src/main/webapp/filters/index.xhtml +++ b/web/web_ui/src/main/webapp/filters/index.xhtml @@ -30,7 +30,23 @@
- + + + + +
+ + + + + diff --git a/web/web_ui/src/main/webapp/scripts/index.xhtml b/web/web_ui/src/main/webapp/scripts/index.xhtml index c58a82012..c995b5509 100644 --- a/web/web_ui/src/main/webapp/scripts/index.xhtml +++ b/web/web_ui/src/main/webapp/scripts/index.xhtml @@ -55,6 +55,21 @@
+ + + + + From 10bc49e9fa7864ef0a9d08f4635f97f75f391ab6 Mon Sep 17 00:00:00 2001 From: zkofiro Date: Mon, 12 Jun 2023 08:50:42 -0700 Subject: [PATCH 40/73] updated tools for changes --- .../rest/mvc/rest/clients/ProjectClient.java | 14 ++-- .../rest/mvc/rest/clients/ScriptClient.java | 14 ++-- .../projects/ProjectServiceV2Impl.java | 3 +- .../services/scripts/ScriptServiceV2Impl.java | 8 +-- .../tank/tools/debugger/ActionProducer.java | 66 ++++++++++--------- 5 files changed, 61 insertions(+), 44 deletions(-) diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java index 7c1104e2b..981c6c0ef 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ProjectClient.java @@ -17,6 +17,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; +import reactor.core.publisher.Flux; import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; @@ -109,18 +110,23 @@ public Map updateProject(AutomationRequest request) { } public String downloadTestScriptForProject(Integer projectId) { - Mono dataBuffer = client.get() + Flux dataBuffers = client.get() .uri(urlBuilder.buildUrl("/download", projectId)) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(DataBuffer.class); + .bodyToFlux(DataBuffer.class) + .cache(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataBufferUtils.write(dataBuffer, baos) - .share().blockLast(); + dataBuffers.doOnNext(dataBuffer -> { + byte[] bytes = new byte[dataBuffer.readableByteCount()]; + dataBuffer.read(bytes); + DataBufferUtils.release(dataBuffer); + baos.write(bytes, 0, bytes.length); + }).blockLast(); return baos.toString(); } diff --git a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java index 7d163ef83..5bb1a3dc5 100644 --- a/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java +++ b/rest-mvc/src/main/java/com/intuit/tank/rest/mvc/rest/clients/ScriptClient.java @@ -18,6 +18,7 @@ import org.springframework.web.reactive.function.client.WebClient; import org.springframework.http.MediaType; import reactor.core.publisher.Mono; +import reactor.core.publisher.Flux; import java.io.ByteArrayOutputStream; import java.util.Map; @@ -93,18 +94,23 @@ public Mono downloadScript(Integer scriptId) { } public String downloadHarnessScript(Integer scriptId) { - Mono dataBuffer = client.get() + Flux dataBuffers = client.get() .uri(urlBuilder.buildUrl("/harness/download", scriptId)) .retrieve() .onStatus(status -> status.isError(), response -> response.bodyToMono(String.class) .flatMap(body -> Mono.error(new ClientException(body, response.statusCode().value())))) - .bodyToMono(DataBuffer.class); + .bodyToFlux(DataBuffer.class) + .cache(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataBufferUtils.write(dataBuffer, baos) - .share().blockLast(); + dataBuffers.doOnNext(dataBuffer -> { + byte[] bytes = new byte[dataBuffer.readableByteCount()]; + dataBuffer.read(bytes); + DataBufferUtils.release(dataBuffer); + baos.write(bytes, 0, bytes.length); + }).blockLast(); return baos.toString(); } 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 6c1400dff..15ceda0d6 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 @@ -74,7 +74,8 @@ public ProjectContainer getAllProjects(){ public Map getAllProjectNames(){ try { List all = new ProjectDao().findAllFast(); - return all.stream().collect(Collectors.toMap(Project::getId, Project::getName)); + return all.stream().sorted(Comparator.comparing(Project::getModified).reversed()) + .collect(Collectors.toMap(Project::getId, Project::getName, (e1, e2) -> e1, LinkedHashMap::new)); } catch (Exception e) { LOGGER.error("Error returning all project names: " + e.getMessage(), e); throw new GenericServiceResourceNotFoundException("projects", "all project names", e); 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 e29a2b655..a07eb6689 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 @@ -38,10 +38,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import java.util.zip.GZIPInputStream; import javax.servlet.ServletContext; @@ -106,7 +103,8 @@ public ScriptDescriptionContainer getScripts() { public Map getAllScriptNames(){ try { List