-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* EPMRPP-93787 Update saucelabs client (#27)
- Loading branch information
Showing
16 changed files
with
434 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
version=5.11.1 | ||
version=5.11.1 | ||
lombokVersion=1.18.34 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,50 +16,73 @@ | |
|
||
package com.epam.reportportal.saucelabs; | ||
|
||
import static com.epam.reportportal.saucelabs.SaucelabsExtension.JOB_ID; | ||
|
||
import com.epam.reportportal.extension.PluginCommand; | ||
import com.epam.ta.reportportal.commons.validation.Suppliers; | ||
import com.epam.reportportal.saucelabs.client.RestClientBuilder; | ||
import com.epam.reportportal.saucelabs.model.SauceProperties; | ||
import com.epam.ta.reportportal.entity.integration.Integration; | ||
import com.epam.ta.reportportal.exception.ReportPortalException; | ||
import com.epam.ta.reportportal.ws.model.ErrorType; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.saucelabs.saucerest.SauceREST; | ||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import java.io.IOException; | ||
import java.util.Map; | ||
|
||
import static com.epam.reportportal.saucelabs.SaucelabsExtension.JOB_ID; | ||
import static com.epam.reportportal.saucelabs.SaucelabsProperties.DATA_CENTER; | ||
import lombok.SneakyThrows; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.json.JSONArray; | ||
import org.json.JSONObject; | ||
import org.springframework.web.client.HttpClientErrorException; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Pavel Bortnik</a> | ||
*/ | ||
@Slf4j | ||
public class AssetsCommand implements PluginCommand<Object> { | ||
|
||
private final RestClient restClient; | ||
private final RestClientBuilder restClient; | ||
|
||
public AssetsCommand(RestClient restClient) { | ||
public AssetsCommand(RestClientBuilder restClient) { | ||
this.restClient = restClient; | ||
} | ||
|
||
@Override | ||
@SneakyThrows | ||
@Override | ||
public Object executeCommand(Integration integration, Map<String, Object> params) { | ||
ValidationUtils.validateParams(params); | ||
SauceREST sauce = restClient.buildSauceClient(integration, (String) params.get(DATA_CENTER.getName())); | ||
String jobId = (String) params.get(JOB_ID); | ||
String assetsPrefix = sauce.getAppServer() + "rest/v1/" + sauce.getUsername() + "/jobs/" + jobId + "/assets/"; | ||
try { | ||
String content = sauce.retrieveResults(sauce.getUsername() + "/jobs/" + jobId + "/assets"); | ||
if (StringUtils.isEmpty(content)) { | ||
throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, | ||
Suppliers.formattedSupplier("Job '{}' not found.", jobId) | ||
); | ||
} | ||
Map<String, String> result = new ObjectMapper().readValue(content, Map.class); | ||
result.put("assetsPrefix", assetsPrefix); | ||
return result; | ||
} catch (IOException e) { | ||
throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, e.getMessage()); | ||
ValidationUtils.validateIntegrationParams(integration.getParams()); | ||
|
||
SauceProperties sp = new SauceProperties(integration.getParams().getParams()); | ||
sp.setJobId((String) params.get(JOB_ID)); | ||
RestTemplate restTemplate = restClient.buildRestTemplate(sp); | ||
|
||
try { | ||
String url = "/rest/v1/" + sp.getUsername() + "/jobs/" + sp.getJobId() + "/assets"; | ||
String jobAssets = restTemplate.getForObject(url, String.class); | ||
JSONObject response = new JSONObject(jobAssets); | ||
response.put("assetsPrefix", | ||
sp.getDatacenter().apiServer + "rest/v1/" + sp.getUsername() + "/jobs/" + sp.getJobId() | ||
+ "/assets"); | ||
return new ObjectMapper().readValue(response.toString(), Object.class); | ||
|
||
} catch (HttpClientErrorException httpException) { | ||
if (httpException.getStatusCode().is4xxClientError()) { | ||
// TODO: handle RD endpoint in a separate plugin command. UI updates required | ||
//String url = sp.getDatacenter().apiServer + "v1/rdc/jobs/" + sp.getJobId(); | ||
//DeviceJob deviceJob = restTemplate.getForObject(url, DeviceJob.class); | ||
|
||
JSONObject response = new JSONObject(); | ||
response.put("assetsPrefix", | ||
String.format("%sv1/rdc/jobs/%s/", sp.getDatacenter().apiServer, sp.getJobId())); | ||
response.put("screenshots", new JSONArray()); | ||
response.put("sauce-log", | ||
String.format("%sv1/rdc/jobs/%s/deviceLogs", sp.getDatacenter().apiServer, | ||
sp.getJobId())); | ||
return new ObjectMapper().readValue(response.toString(), Object.class); | ||
|
||
} else { | ||
throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, StringUtils.normalizeSpace("Failed to retrieve job assets")); | ||
} | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,21 @@ | ||
package com.epam.reportportal.saucelabs; | ||
|
||
import static com.epam.reportportal.saucelabs.SaucelabsExtension.JOB_ID; | ||
import static com.epam.reportportal.saucelabs.SaucelabsProperties.ACCESS_TOKEN; | ||
import static com.epam.reportportal.saucelabs.SaucelabsProperties.USERNAME; | ||
import static com.epam.reportportal.saucelabs.ValidationUtils.validateIntegrationParams; | ||
import static com.epam.reportportal.saucelabs.ValidationUtils.validateParams; | ||
|
||
import com.epam.reportportal.extension.PluginCommand; | ||
import com.epam.ta.reportportal.entity.integration.Integration; | ||
import com.epam.ta.reportportal.exception.ReportPortalException; | ||
import com.epam.ta.reportportal.ws.model.ErrorType; | ||
import org.apache.commons.codec.binary.Hex; | ||
import org.jasypt.util.text.BasicTextEncryptor; | ||
|
||
import javax.crypto.Mac; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Collections; | ||
import java.util.Map; | ||
|
||
import static com.epam.reportportal.saucelabs.SaucelabsExtension.JOB_ID; | ||
import static com.epam.reportportal.saucelabs.SaucelabsProperties.ACCESS_TOKEN; | ||
import static com.epam.reportportal.saucelabs.SaucelabsProperties.USERNAME; | ||
import static com.epam.reportportal.saucelabs.ValidationUtils.validateParams; | ||
import javax.crypto.Mac; | ||
import javax.crypto.spec.SecretKeySpec; | ||
import org.apache.commons.codec.binary.Hex; | ||
import org.jasypt.util.text.BasicTextEncryptor; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Pavel Bortnik</a> | ||
|
@@ -33,13 +32,13 @@ public GenerateAuthTokenCommand(BasicTextEncryptor textEncryptor) { | |
public Object executeCommand(Integration integration, Map params) { | ||
try { | ||
validateParams(params); | ||
validateIntegrationParams(integration.getParams()); | ||
|
||
String username = USERNAME.getParam(integration.getParams()) | ||
.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, "Username is not specified.")); | ||
; | ||
String accessToken = textEncryptor.decrypt(ACCESS_TOKEN.getParam(integration.getParams()) | ||
.orElseThrow(() -> new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, | ||
"Access token is not specified." | ||
))); | ||
|
||
); | ||
|
||
SecretKeySpec keySpec = new SecretKeySpec((username + ":" + accessToken).getBytes(StandardCharsets.UTF_8), "HmacMD5"); | ||
Mac mac = Mac.getInstance("HmacMD5"); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,52 +16,75 @@ | |
|
||
package com.epam.reportportal.saucelabs; | ||
|
||
import static com.epam.reportportal.saucelabs.SaucelabsExtension.JOB_ID; | ||
|
||
import com.epam.reportportal.extension.PluginCommand; | ||
import com.epam.ta.reportportal.commons.validation.Suppliers; | ||
import com.epam.reportportal.saucelabs.client.RestClientBuilder; | ||
import com.epam.reportportal.saucelabs.model.SauceProperties; | ||
import com.epam.ta.reportportal.entity.integration.Integration; | ||
import com.epam.ta.reportportal.exception.ReportPortalException; | ||
import com.epam.ta.reportportal.ws.model.ErrorType; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.saucelabs.saucerest.SauceREST; | ||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import java.io.IOException; | ||
import java.util.Map; | ||
|
||
import static com.epam.reportportal.saucelabs.SaucelabsExtension.JOB_ID; | ||
import static com.epam.reportportal.saucelabs.SaucelabsProperties.DATA_CENTER; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.springframework.web.client.HttpClientErrorException; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Pavel Bortnik</a> | ||
*/ | ||
@Slf4j | ||
public class GetLogsCommand implements PluginCommand<Object> { | ||
|
||
private final RestClient restClient; | ||
private final RestClientBuilder restClient; | ||
|
||
public GetLogsCommand(RestClientBuilder restClient) { | ||
this.restClient = restClient; | ||
} | ||
|
||
@Override | ||
public Object executeCommand(Integration integration, Map<String, Object> params) { | ||
ValidationUtils.validateParams(params); | ||
ValidationUtils.validateIntegrationParams(integration.getParams()); | ||
SauceProperties sp = new SauceProperties(integration.getParams().getParams()); | ||
sp.setJobId((String) params.get(JOB_ID)); | ||
return getWebDriverLogs(restClient.buildRestTemplate(sp), sp); | ||
} | ||
|
||
private Object getWebDriverLogs(RestTemplate restTemplate, SauceProperties sp) { | ||
try { | ||
String url = getJobAssetsUrl(sp) + "/log.json"; | ||
return restTemplate.getForObject(url, Object.class); | ||
} catch (HttpClientErrorException httpException) { | ||
|
||
if (httpException.getStatusCode().is4xxClientError()) { | ||
return getRealDeviceLogs(restTemplate, sp); | ||
|
||
} else { | ||
throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, | ||
StringUtils.normalizeSpace("Failed to retrieve job assets")); | ||
} | ||
} | ||
} | ||
|
||
public GetLogsCommand(RestClient restClient) { | ||
this.restClient = restClient; | ||
} | ||
// TODO: handle RD endpoint in a separate plugin command. UI updates required | ||
private Object getRealDeviceLogs(RestTemplate restTemplate, SauceProperties sp) { | ||
String url = "/v1/rdc/jobs/" + sp.getJobId() + "/deviceLogs"; | ||
return restTemplate.getForObject(url, Object.class); | ||
} | ||
|
||
@Override | ||
public Object executeCommand(Integration system, Map<String, Object> params) { | ||
ValidationUtils.validateParams(params); | ||
SauceREST sauce = restClient.buildSauceClient(system, (String) params.get(DATA_CENTER.getName())); | ||
try { | ||
String jobId = (String) params.get(JOB_ID); | ||
String content = sauce.retrieveResults(sauce.getUsername() + "/jobs/" + jobId + "/assets/log.json"); | ||
if (StringUtils.isEmpty(content)) { | ||
throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, | ||
Suppliers.formattedSupplier("Job '{}' not found.", jobId) | ||
); | ||
} | ||
return new ObjectMapper().readValue(content, Object.class); | ||
} catch (IOException e) { | ||
throw new ReportPortalException(ErrorType.UNABLE_INTERACT_WITH_INTEGRATION, e.getMessage()); | ||
} | ||
} | ||
@Override | ||
public String getName() { | ||
return "logs"; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "logs"; | ||
} | ||
private String getJobAssetsUrl(SauceProperties sp) { | ||
return new StringBuilder() | ||
.append("/rest/v1/") | ||
.append(sp.getUsername()) | ||
.append("/jobs/") | ||
.append(sp.getJobId()) | ||
.append("/assets") | ||
.toString(); | ||
} | ||
} |
Oops, something went wrong.