Java tutorial
/* * Copyright (C) 2014 Stratio (http://stratio.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.stratio.qa.specs; import com.datastax.driver.core.ColumnDefinitions; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Row; import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.spi.json.GsonJsonProvider; import com.jayway.jsonpath.spi.mapper.GsonMappingProvider; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.AsyncHttpClient.BoundRequestBuilder; import com.ning.http.client.Realm; import com.ning.http.client.Realm.AuthScheme; import com.ning.http.client.Response; import com.ning.http.client.cookie.Cookie; import com.stratio.qa.conditions.Conditions; import com.stratio.qa.utils.*; import cucumber.api.DataTable; import org.apache.commons.collections.IteratorUtils; import org.apache.commons.io.FileUtils; import org.assertj.core.api.Assertions; import org.assertj.core.api.Condition; import org.hjson.JsonArray; import org.hjson.JsonObject; import org.hjson.JsonType; import org.hjson.JsonValue; import org.json.JSONArray; import org.json.JSONObject; import org.openqa.selenium.*; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.internal.Locatable; import org.openqa.selenium.remote.RemoteWebDriver; import org.reflections.Reflections; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.sql.Timestamp; import java.util.*; import java.util.concurrent.Future; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.stratio.qa.assertions.Assertions.assertThat; import static org.testng.Assert.fail; public class CommonG { private static final long DEFAULT_CURRENT_TIME = 1000L; private static final int DEFAULT_SLEEP_TIME = 1500; private final Logger logger = LoggerFactory.getLogger(ThreadProperty.get("class")); private RemoteWebDriver driver = null; private String browserName = null; private PreviousWebElements previousWebElements = null; private String parentWindow = ""; private AsyncHttpClient client; private HttpResponse response; private List<Cookie> cookies = new ArrayList<Cookie>(); private ResultSet previousCassandraResults; private DBCursor previousMongoResults; private List<JSONObject> previousElasticsearchResults; private List<Map<String, String>> previousCSVResults; private String resultsType = ""; private Set<org.openqa.selenium.Cookie> seleniumCookies = new HashSet<org.openqa.selenium.Cookie>(); private Map<String, String> headers = new HashMap<>(); private String restHost; private String restPort; private String webHost; private String webPort; private RemoteSSHConnection remoteSSHConnection; private int commandExitStatus; private String commandResult; private String restProtocol; private ZookeeperSecUtils zkSecClient; /** * Checks if a given string matches a regular expression or contains a string * * @param expectedMessage message used for comparing * @return boolean */ public static Pattern matchesOrContains(String expectedMessage) { Pattern pattern; if (expectedMessage.startsWith("regex:")) { String regex = expectedMessage.substring(expectedMessage.indexOf("regex:") + 6, expectedMessage.length()); pattern = Pattern.compile(regex); } else { pattern = Pattern.compile(Pattern.quote(expectedMessage)); } return pattern; } /** * Get the common remote connection. * * @return RemoteConnection */ public RemoteSSHConnection getRemoteSSHConnection() { return remoteSSHConnection; } /** * Set the remote connection. */ public void setRemoteSSHConnection(RemoteSSHConnection remoteSSHConnection) { this.remoteSSHConnection = remoteSSHConnection; } /** * Get the common REST host. * * @return String */ public String getRestHost() { return this.restHost; } /** * Set the REST host. * * @param restHost api host */ public void setRestHost(String restHost) { this.restHost = restHost; } /** * Get the common REST port. * * @return String */ public String getRestPort() { return this.restPort; } /** * Set the REST port. * * @param restPort api port */ public void setRestPort(String restPort) { this.restPort = restPort; } /** * Get the common WEB host. * * @return String */ public String getWebHost() { return this.webHost; } /** * Set the WEB host. * * @param webHost host where app is running */ public void setWebHost(String webHost) { this.webHost = webHost; } /** * Get the common WEB port. * * @return String */ public String getWebPort() { return this.webPort; } /** * Set the WEB port. * * @param webPort port where app is running */ public void setWebPort(String webPort) { this.webPort = webPort; } /** * Get the common logger. * * @return Logger */ public Logger getLogger() { return this.logger; } /** * Get the exception list. * * @return List(Exception) */ public List<Exception> getExceptions() { return ExceptionList.INSTANCE.getExceptions(); } /** * Get the textFieldCondition list. * * @return List(Exception) */ public Condition<WebElement> getTextFieldCondition() { return Conditions.INSTANCE.getTextFieldCondition(); } /** * Get the cassandra utils. * * @return CassandraUtils */ public CassandraUtils getCassandraClient() { return CassandraUtil.INSTANCE.getCassandraUtils(); } /** * Get the elasticSearch utils. * * @return ElasticSearchUtils */ public ElasticSearchUtils getElasticSearchClient() { return ElasticSearchUtil.INSTANCE.getElasticSearchUtils(); } /** * Get the Kafka utils. * * @return KafkaUtils */ public KafkaUtils getKafkaUtils() { return KafkaUtil.INSTANCE.getKafkaUtils(); } /** * Get the MongoDB utils. * * @return MongoDBUtils */ public MongoDBUtils getMongoDBClient() { return MongoDBUtil.INSTANCE.getMongoDBUtils(); } /** * Get the Zookeeper Sec utils. * * @return ZookeperSecUtils */ public ZookeeperSecUtils getZookeeperSecClient() { return ZookeeperSecUtil.INSTANCE.getZookeeperSecUtils(); } /** * Get the remoteWebDriver. * * @return RemoteWebDriver */ public RemoteWebDriver getDriver() { return driver; } /** * Set the remoteDriver. * * @param driver driver to be used for testing */ public void setDriver(RemoteWebDriver driver) { this.driver = driver; } /** * Get the browser name. * * @return String */ public String getBrowserName() { return browserName; } /** * Set the browser name. * * @param browserName browser to be used for testing */ public void setBrowserName(String browserName) { this.browserName = browserName; } /** * Looks for webelements inside a selenium context. This search will be made * by id, name and xpath expression matching an {@code locator} value * * @param method class of element to be searched * @param element webElement searched in selenium context * @param expectedCount integer. Expected number of elements. * @return List(WebElement) * @throws IllegalAccessException exception * @throws IllegalArgumentException exception * @throws SecurityException exception * @throws NoSuchFieldException exception * @throws ClassNotFoundException exception */ public List<WebElement> locateElement(String method, String element, Integer expectedCount) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { List<WebElement> wel = null; if ("id".equals(method)) { logger.debug("Locating {} by id", element); wel = this.getDriver().findElements(By.id(element)); } else if ("name".equals(method)) { logger.debug("Locating {} by name", element); wel = this.getDriver().findElements(By.name(element)); } else if ("class".equals(method)) { logger.debug("Locating {} by class", element); wel = this.getDriver().findElements(By.className(element)); } else if ("xpath".equals(method)) { logger.debug("Locating {} by xpath", element); wel = this.getDriver().findElements(By.xpath(element)); } else if ("css".equals(method)) { wel = this.getDriver().findElements(By.cssSelector(element)); } else { fail("Unknown search method: " + method); } if (expectedCount != -1) { PreviousWebElements pwel = new PreviousWebElements(wel); assertThat(this, pwel).as("Element count doesnt match").hasSize(expectedCount); } return wel; } /** * Capture a snapshot or an evidence in the driver * * @param driver driver used for testing * @param type type * @return String */ public String captureEvidence(WebDriver driver, String type) { return captureEvidence(driver, type, ""); } /** * Capture a snapshot or an evidence in the driver * * @param driver driver used for testing * @param type type * @param suffix suffix * @return String */ public String captureEvidence(WebDriver driver, String type, String suffix) { String testSuffix = System.getProperty("TESTSUFFIX"); String dir = "./target/executions/"; if (testSuffix != null) { dir = dir + testSuffix + "/"; } String clazz = ThreadProperty.get("class"); String currentBrowser = ThreadProperty.get("browser"); String currentData = ThreadProperty.get("dataSet"); if (!currentData.equals("")) { currentData = currentData.replaceAll("[\\\\|\\/|\\|\\s|:|\\*]", "_"); } if (!"".equals(currentData)) { currentData = "-" + HashUtils.doHash(currentData); } Timestamp ts = new Timestamp(new java.util.Date().getTime()); String outputFile = dir + clazz + "/" + ThreadProperty.get("feature") + "." + ThreadProperty.get("scenario") + "/" + currentBrowser + currentData + ts.toString() + suffix; outputFile = outputFile.replaceAll(" ", "_"); if (type.endsWith("htmlSource")) { if (type.equals("framehtmlSource")) { boolean isFrame = (Boolean) ((JavascriptExecutor) driver) .executeScript("return window.top != window.self"); if (isFrame) { outputFile = outputFile + "frame.html"; } else { outputFile = ""; } } else if (type.equals("htmlSource")) { driver.switchTo().defaultContent(); outputFile = outputFile + ".html"; } if (!outputFile.equals("")) { String source = ((RemoteWebDriver) driver).getPageSource(); File fout = new File(outputFile); boolean dirs = fout.getParentFile().mkdirs(); FileOutputStream fos; try { fos = new FileOutputStream(fout, true); Writer out = new OutputStreamWriter(fos, "UTF8"); PrintWriter writer = new PrintWriter(out, false); writer.append(source); writer.close(); out.close(); } catch (IOException e) { logger.error("Exception on evidence capture", e); } } } else if ("screenCapture".equals(type)) { outputFile = outputFile + ".png"; File file = null; driver.switchTo().defaultContent(); ((Locatable) driver.findElement(By.tagName("body"))).getCoordinates().inViewPort(); if (currentBrowser.startsWith("chrome") || currentBrowser.startsWith("droidemu")) { Actions actions = new Actions(driver); actions.keyDown(Keys.CONTROL).sendKeys(Keys.HOME).perform(); actions.keyUp(Keys.CONTROL).perform(); file = chromeFullScreenCapture(driver); } else { file = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); } try { FileUtils.copyFile(file, new File(outputFile)); } catch (IOException e) { logger.error("Exception on copying browser screen capture", e); } } return outputFile; } private File adjustLastCapture(Integer newTrailingImageHeight, List<File> capture) { // cuts last image just in case it dupes information Integer finalHeight = 0; Integer finalWidth = 0; File trailingImage = capture.get(capture.size() - 1); capture.remove(capture.size() - 1); BufferedImage oldTrailingImage; File temp = null; try { oldTrailingImage = ImageIO.read(trailingImage); BufferedImage newTrailingImage = new BufferedImage(oldTrailingImage.getWidth(), oldTrailingImage.getHeight() - newTrailingImageHeight, BufferedImage.TYPE_INT_RGB); newTrailingImage.createGraphics().drawImage(oldTrailingImage, 0, 0 - newTrailingImageHeight, null); File newTrailingImageF = File.createTempFile("tmpnewTrailingImage", ".png"); newTrailingImageF.deleteOnExit(); ImageIO.write(newTrailingImage, "png", newTrailingImageF); capture.add(newTrailingImageF); finalWidth = ImageIO.read(capture.get(0)).getWidth(); for (File cap : capture) { finalHeight += ImageIO.read(cap).getHeight(); } BufferedImage img = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_RGB); Integer y = 0; BufferedImage tmpImg = null; for (File cap : capture) { tmpImg = ImageIO.read(cap); img.createGraphics().drawImage(tmpImg, 0, y, null); y += tmpImg.getHeight(); } long ts = System.currentTimeMillis() / DEFAULT_CURRENT_TIME; temp = File.createTempFile("chromecap" + Long.toString(ts), ".png"); temp.deleteOnExit(); ImageIO.write(img, "png", temp); } catch (IOException e) { logger.error("Cant read image", e); } return temp; } private File chromeFullScreenCapture(WebDriver driver) { driver.switchTo().defaultContent(); // scroll loop n times to get the whole page if browser is chrome ArrayList<File> capture = new ArrayList<File>(); Boolean atBottom = false; Integer windowSize = ((Long) ((JavascriptExecutor) driver) .executeScript("return document.documentElement.clientHeight")).intValue(); Integer accuScroll = 0; Integer newTrailingImageHeight = 0; try { while (!atBottom) { Thread.sleep(DEFAULT_SLEEP_TIME); capture.add(((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE)); ((JavascriptExecutor) driver) .executeScript("if(window.screen)" + " {window.scrollBy(0," + windowSize + ");};"); accuScroll += windowSize; if (getDocumentHeight(driver) <= accuScroll) { atBottom = true; } } } catch (InterruptedException e) { logger.error("Interrupted waits among scrolls", e); } newTrailingImageHeight = accuScroll - getDocumentHeight(driver); return adjustLastCapture(newTrailingImageHeight, capture); } private Integer getDocumentHeight(WebDriver driver) { WebElement body = driver.findElement(By.tagName("html")); return body.getSize().getHeight(); } /** * Returns the previous webElement * * @return List(WebElement) */ public PreviousWebElements getPreviousWebElements() { return previousWebElements; } /** * Set the previous webElement */ public void setPreviousWebElements(PreviousWebElements previousWebElements) { this.previousWebElements = previousWebElements; } /** * Returns the parentWindow * * @return String */ public String getParentWindow() { return this.parentWindow; } /** * Sets the parentWindow */ public void setParentWindow(String windowHandle) { this.parentWindow = windowHandle; } // COPIED FROM COMMON.JAVA public AsyncHttpClient getClient() { return client; } public void setClient(AsyncHttpClient client) { this.client = client; } public HttpResponse getResponse() { return response; } public void setResponse(String endpoint, Response response) throws IOException { Integer statusCode = response.getStatusCode(); String httpResponse = response.getResponseBody(); List<Cookie> cookies = response.getCookies(); this.response = new HttpResponse(statusCode, httpResponse, cookies); } /** * Returns the information contained in file passed as parameter * * @param baseData path to file to be read * @param type type of information, it can be: json|string * @return String */ public String retrieveData(String baseData, String type) { String result; InputStream stream = getClass().getClassLoader().getResourceAsStream(baseData); Writer writer = new StringWriter(); char[] buffer = new char[1024]; Reader reader; if (stream == null) { this.getLogger().error("File does not exist: {}", baseData); return "ERR! File not found: " + baseData; } try { reader = new BufferedReader(new InputStreamReader(stream, "UTF-8")); int n; while ((n = reader.read(buffer)) != -1) { writer.write(buffer, 0, n); } } catch (Exception readerexception) { this.getLogger().error(readerexception.getMessage()); } finally { try { stream.close(); } catch (Exception closeException) { this.getLogger().error(closeException.getMessage()); } } String text = writer.toString(); String std = text.replace("\r", "").replace("\n", ""); // make sure we have unix style text regardless of the input if ("json".equals(type)) { result = JsonValue.readHjson(std).asObject().toString(); } else { result = std; } return result; } /** * Returns the information modified * * @param data string containing the information * @param type type of information, it can be: json|string * @param modifications modifications to apply with a format: * WHERE,ACTION,VALUE * <p> * {@code * DELETE: Delete the key in json or string in current value * in case of DELETE action modifications is |key1|DELETE|N/A| * and with json {"key1":"value1","key2":{"key3":null}} * returns {"key2":{"key3":null}} * Example 2: * {"key1":"val1", "key2":"val2"} -> | key1 | DELETE | N/A | -> {"key2":"val2"} * "mystring" -> | str | DELETE | N/A | -> "mying" * } * <p> * {@code * ADD: Add new key to json or append string to current value. * in case of ADD action is |N/A|ADD|&config=config|, * and with data username=username&password=password * returns username=username&password=password&config=config * Example 2: * {"key1":"val1", "key2":"val2"} -> | key3 | ADD | val3 | -> {"key1":"val1", "key2":"val2", "key3":"val3"} * "mystring" -> | N/A | ADD | new | -> "mystringnew" * } * <p> * {@code * UPDATE: Update value in key or modify part of string. * in case of UPDATE action is |username=username|UPDATE|username=NEWusername|, * and with data username=username&password=password * returns username=NEWusername&password=password * Example 2: * {"key1":"val1", "key2":"val2"} -> | key1 | UPDATE | newval1 | -> {"key1":"newval1", "key2":"val2"} * "mystring" -> | str | UPDATE | mod | -> "mymoding" * } * <p> * {@code * PREPEND: Prepend value to key value or to string * in case of PREPEND action is |username=username|PREPEND|key1=value1&|, * and with data username=username&password=password * returns key1=value1&username=username&password=password * Example 2: * {"key1":"val1", "key2":"val2"} -> | key1 | PREPEND | new | -> {"key1":"newval1", "key2":"val2"} * "mystring" -> | N/A | PREPEND | new | -> "newmystring" * } * <p> * {@code * REPLACE: Update value in key or modify part of string. * in case of REPLACE action is |key2.key3|REPLACE|lu->REPLACE| * and with json {"key1":"value1","key2":{"key3":"value3"}} * returns {"key1":"value1","key2":{"key3":"vaREPLACEe3"}} * the format is (WHERE, ACTION, CHANGE FROM -> TO). * REPLACE replaces a string or its part per other string * } * <p> * {@code * if modifications has fourth argument, the replacement is effected per special json object * the format is: * (WHERE, ACTION, CHANGE_TO, JSON_TYPE), * WHERE is the key, ACTION is REPLACE, * CHANGE_TO is the new value of the key, * JSON_TYPE is the type of jason object, * there are 5 special cases of json object replacements: * array|object|number|boolean|null * } * <p> * {@code * example1: |key2.key3|REPLACE|5|number| * with json {"key1":"value1","key2":{"key3":"value3"}} * returns {"key1":"value1","key2":{"key3":5}} * in this case it replaces value of key3 * per jason number * }<p> * {@code * example2: |key2.key3|REPLACE|{}|object| * with json {"key1":"value1","key2":{"key3":"value3"}} * returns {"key1":"value1","key2":{"key3":{}}} * in this case it replaces per empty json object * }<p> * {@code * APPEND: Append value to key value or to string * {"key1":"val1", "key2":"val2"} -> | key1 | APPEND | new | -> {"key1":"val1new", "key2":"val2"} * "mystring" -> | N/A | APPEND | new | -> "mystringnew" * } * @return String * @throws Exception */ public String modifyData(String data, String type, DataTable modifications) throws Exception { String modifiedData = data; String typeJsonObject = ""; String nullValue = ""; JSONArray jArray; JSONObject jObject; Double jNumber; Boolean jBoolean; if ("json".equals(type)) { LinkedHashMap jsonAsMap = new LinkedHashMap(); for (int i = 0; i < modifications.raw().size(); i++) { String composeKey = modifications.raw().get(i).get(0); String operation = modifications.raw().get(i).get(1); String newValue = modifications.raw().get(i).get(2); if (modifications.raw().get(0).size() == 4) { typeJsonObject = modifications.raw().get(i).get(3); } JsonObject object = new JsonObject(JsonValue.readHjson(modifiedData).asObject()); removeNulls(object); modifiedData = JsonValue.readHjson(object.toString()).toString(); switch (operation.toUpperCase()) { case "DELETE": jsonAsMap = JsonPath.parse(modifiedData).delete(composeKey).json(); break; case "ADD": // Get the last key String newKey; String newComposeKey; if (composeKey.contains(".")) { newKey = composeKey.substring(composeKey.lastIndexOf('.') + 1); newComposeKey = composeKey.substring(0, composeKey.lastIndexOf('.')); } else { newKey = composeKey; newComposeKey = "$"; } jsonAsMap = JsonPath.parse(modifiedData).put(newComposeKey, newKey, newValue).json(); break; case "UPDATE": jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, newValue).json(); break; case "APPEND": String appendValue = JsonPath.parse(modifiedData).read(composeKey); jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, appendValue + newValue).json(); break; case "PREPEND": String prependValue = JsonPath.parse(modifiedData).read(composeKey); jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, newValue + prependValue).json(); break; case "REPLACE": if ("array".equals(typeJsonObject)) { jArray = new JSONArray(); if (!"[]".equals(newValue)) { jArray = new JSONArray(newValue); } jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, jArray).json(); break; } else if ("object".equals(typeJsonObject)) { jObject = new JSONObject(); if (!"{}".equals(newValue)) { jObject = new JSONObject(newValue); } jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, jObject).json(); break; } else if ("string".equals(typeJsonObject)) { jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, newValue).json(); break; } else if ("number".equals(typeJsonObject)) { jNumber = new Double(newValue); jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, jNumber).json(); break; } else if ("boolean".equals(typeJsonObject)) { jBoolean = new Boolean(newValue); jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, jBoolean).json(); break; } else if ("null".equals(typeJsonObject)) { nullValue = JsonPath.parse(modifiedData).set(composeKey, null).jsonString(); break; } else { String replaceValue = JsonPath.parse(modifiedData).read(composeKey); String toBeReplaced = newValue.split("->")[0]; String replacement = newValue.split("->")[1]; newValue = replaceValue.replace(toBeReplaced, replacement); jsonAsMap = JsonPath.parse(modifiedData).set(composeKey, newValue).json(); break; } case "ADDTO": if ("array".equals(typeJsonObject)) { jArray = new JSONArray(); if (!"[]".equals(newValue)) { jArray = new JSONArray(newValue); } jsonAsMap = JsonPath.parse(modifiedData).add(composeKey, jArray).json(); break; } else if ("object".equals(typeJsonObject)) { jObject = new JSONObject(); if (!"{}".equals(newValue)) { jObject = new JSONObject(newValue); } jsonAsMap = JsonPath.parse(modifiedData).add(composeKey, jObject).json(); break; } else if ("string".equals(typeJsonObject)) { jsonAsMap = JsonPath.parse(modifiedData).add(composeKey, newValue).json(); break; } else if ("number".equals(typeJsonObject)) { jNumber = new Double(newValue); jsonAsMap = JsonPath.parse(modifiedData).add(composeKey, jNumber).json(); break; } else if ("boolean".equals(typeJsonObject)) { jBoolean = new Boolean(newValue); jsonAsMap = JsonPath.parse(modifiedData).add(composeKey, jBoolean).json(); break; } else if ("null".equals(typeJsonObject)) { nullValue = JsonPath.parse(modifiedData).add(composeKey, null).jsonString(); break; } else { // TO-DO: understand newValue.split("->")[0]; and newValue.split("->")[1]; break; } case "HEADER": this.headers.put(composeKey, newValue); break; default: throw new Exception("Modification type does not exist: " + operation); } modifiedData = new JSONObject(jsonAsMap).toString(); if (!"".equals(nullValue)) { modifiedData = nullValue; } modifiedData = modifiedData.replaceAll("\"TO_BE_NULL\"", "null"); } } else { for (int i = 0; i < modifications.raw().size(); i++) { String value = modifications.raw().get(i).get(0); String operation = modifications.raw().get(i).get(1); String newValue = modifications.raw().get(i).get(2); switch (operation.toUpperCase()) { case "DELETE": modifiedData = modifiedData.replace(value, ""); break; case "ADD": case "APPEND": modifiedData = modifiedData + newValue; break; case "UPDATE": case "REPLACE": modifiedData = modifiedData.replace(value, newValue); break; case "PREPEND": modifiedData = newValue + modifiedData; break; case "HEADER": this.headers.put(value, newValue); break; default: throw new Exception("Modification type does not exist: " + operation); } } } return modifiedData; } /** * Eliminates null occurrences, replacing them with "TO_BE_NULL" * * @param object JsonObject containing json where to replace null ocurrences * @return JsonObject */ public JsonObject removeNulls(JsonObject object) { for (int j = 0; j < object.names().size(); j++) { if (JsonType.OBJECT.equals(object.get(object.names().get(j)).getType())) { removeNulls(object.get(object.names().get(j)).asObject()); } else { if (object.get(object.names().get(j)).isNull()) { object.set(object.names().get(j), "TO_BE_NULL"); } } } return object; } /** * Generates the request based on the type of request, the end point, the data and type passed * * @param requestType type of request to be sent * @param secure type of protocol * @param user user to be used in request * @param password password to be used in request * @param endPoint end point to sent the request to * @param data to be sent for PUT/POST requests * @param type type of data to be sent (json|string) * @param codeBase64 XXX * @throws Exception exception */ @Deprecated public Future<Response> generateRequest(String requestType, boolean secure, String user, String password, String endPoint, String data, String type, String codeBase64) throws Exception { return generateRequest(requestType, secure, user, password, endPoint, data, type); } /** * Generates the request based on the type of request, the end point, the data and type passed * * @param requestType type of request to be sent * @param secure type of protocol * @param user user to be used in request * @param password password to be used in request * @param endPoint end point to sent the request to * @param data to be sent for PUT/POST requests * @param type type of data to be sent (json|string) * @throws Exception exception */ public Future<Response> generateRequest(String requestType, boolean secure, String user, String password, String endPoint, String data, String type) throws Exception { String protocol = this.getRestProtocol(); Future<Response> response = null; BoundRequestBuilder request; Realm realm = null; if (this.getRestHost() == null) { throw new Exception("Rest host has not been set"); } if (this.getRestPort() == null) { throw new Exception("Rest port has not been set"); } if (this.getRestProtocol() == null) { protocol = "http://"; } String restURL = protocol + this.getRestHost() + this.getRestPort(); // Setup user and password for requests if (user != null) { realm = new Realm.RealmBuilder().setPrincipal(user).setPassword(password).setUsePreemptiveAuth(true) .setScheme(AuthScheme.BASIC).build(); } switch (requestType.toUpperCase()) { case "GET": request = this.getClient().prepareGet(restURL + endPoint); if ("json".equals(type)) { request = request.setHeader("Content-Type", "application/json"); } else if ("string".equals(type)) { this.getLogger().debug("Sending request as: {}", type); request = request.setHeader("Content-Type", "application/x-www-form-urlencoded"); } if (this.getResponse() != null) { this.getLogger().debug("Reusing coookies: {}", this.getResponse().getCookies()); request = request.setCookies(this.getResponse().getCookies()); } for (Cookie cook : this.getCookies()) { request = request.addCookie(cook); } if (this.getSeleniumCookies().size() > 0) { for (org.openqa.selenium.Cookie cookie : this.getSeleniumCookies()) { request.addCookie(new Cookie(cookie.getName(), cookie.getValue(), false, cookie.getDomain(), cookie.getPath(), 99, false, false)); } } if (!this.headers.isEmpty()) { for (Map.Entry<String, String> header : headers.entrySet()) { request = request.setHeader(header.getKey(), header.getValue()); } } if (user != null) { request = request.setRealm(realm); } response = request.execute(); break; case "DELETE": request = this.getClient().prepareDelete(restURL + endPoint); if (this.getResponse() != null) { request = request.setCookies(this.getResponse().getCookies()); } if (this.getSeleniumCookies().size() > 0) { for (org.openqa.selenium.Cookie cookie : this.getSeleniumCookies()) { request.addCookie(new Cookie(cookie.getName(), cookie.getValue(), false, cookie.getDomain(), cookie.getPath(), 99, false, false)); } } for (Cookie cook : this.getCookies()) { request = request.addCookie(cook); } if (!this.headers.isEmpty()) { for (Map.Entry<String, String> header : headers.entrySet()) { request = request.setHeader(header.getKey(), header.getValue()); } } if (user != null) { request = request.setRealm(realm); } response = request.execute(); break; case "POST": if (data == null) { Exception missingFields = new Exception("Missing fields in request."); throw missingFields; } else { request = this.getClient().preparePost(restURL + endPoint).setBody(data); if ("json".equals(type)) { request = request.setHeader("Content-Type", "application/json"); } else if ("string".equals(type)) { this.getLogger().debug("Sending request as: {}", type); request = request.setHeader("Content-Type", "application/x-www-form-urlencoded"); } if (this.getResponse() != null) { request = request.setCookies(this.getResponse().getCookies()); } if (this.getSeleniumCookies().size() > 0) { for (org.openqa.selenium.Cookie cookie : this.getSeleniumCookies()) { request.addCookie(new Cookie(cookie.getName(), cookie.getValue(), false, cookie.getDomain(), cookie.getPath(), 99, false, false)); } } for (Cookie cook : this.getCookies()) { request = request.addCookie(cook); } if (!this.headers.isEmpty()) { for (Map.Entry<String, String> header : headers.entrySet()) { request = request.setHeader(header.getKey(), header.getValue()); } } if (user != null) { request = request.setRealm(realm); } response = this.getClient().executeRequest(request.build()); break; } case "PUT": if (data == null) { Exception missingFields = new Exception("Missing fields in request."); throw missingFields; } else { request = this.getClient().preparePut(restURL + endPoint).setBody(data); if ("json".equals(type)) { request = request.setHeader("Content-Type", "application/json"); } else if ("string".equals(type)) { request = request.setHeader("Content-Type", "application/x-www-form-urlencoded"); } if (this.getResponse() != null) { request = request.setCookies(this.getResponse().getCookies()); } if (this.getSeleniumCookies().size() > 0) { for (org.openqa.selenium.Cookie cookie : this.getSeleniumCookies()) { request.addCookie(new Cookie(cookie.getName(), cookie.getValue(), false, cookie.getDomain(), cookie.getPath(), 99, false, false)); } } for (Cookie cook : this.getCookies()) { request = request.addCookie(cook); } if (!this.headers.isEmpty()) { for (Map.Entry<String, String> header : headers.entrySet()) { request = request.setHeader(header.getKey(), header.getValue()); } } if (user != null) { request = request.setRealm(realm); } response = this.getClient().executeRequest(request.build()); break; } case "CONNECT": case "PATCH": case "HEAD": case "OPTIONS": case "REQUEST": case "TRACE": throw new Exception("Operation not implemented: " + requestType); default: throw new Exception("Operation not valid: " + requestType); } return response; } /** * Generates the request based on the type of request, the end point, the data and type passed * * @param requestType type of request to be sent * @param secure type of protocol * @param endPoint end point to sent the request to * @param data to be sent for PUT/POST requests * @param type type of data to be sent (json|string) * @throws Exception exception */ @Deprecated public Future<Response> generateRequest(String requestType, boolean secure, String endPoint, String data, String type, String codeBase64) throws Exception { return generateRequest(requestType, false, null, null, endPoint, data, type, ""); } /** * Saves the value in the attribute in class extending CommonG. * * @param element attribute in class where to store the value * @param value value to be stored * @throws NoSuchFieldException exception * @throws SecurityException exception * @throws IllegalArgumentException exception * @throws IllegalAccessException exception * @throws InstantiationException exception * @throws ClassNotFoundException exception * @throws NoSuchMethodException exception * @throws InvocationTargetException exception */ public void setPreviousElement(String element, String value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException { Reflections reflections = new Reflections("com.stratio"); Set classes = reflections.getSubTypesOf(CommonG.class); Object pp = (classes.toArray())[0]; String qq = (pp.toString().split(" "))[1]; Class<?> c = Class.forName(qq.toString()); Field ff = c.getDeclaredField(element); ff.setAccessible(true); ff.set(null, value); } public ResultSet getCassandraResults() { return previousCassandraResults; } public void setCassandraResults(ResultSet results) { this.previousCassandraResults = results; } public DBCursor getMongoResults() { return previousMongoResults; } public void setMongoResults(DBCursor results) { this.previousMongoResults = results; } public List<JSONObject> getElasticsearchResults() { return previousElasticsearchResults; } public void setElasticsearchResults(List<JSONObject> results) { this.previousElasticsearchResults = results; } public List<Map<String, String>> getCSVResults() { return previousCSVResults; } public void setCSVResults(List<Map<String, String>> results) { this.previousCSVResults = results; } public String getResultsType() { return resultsType; } public void setResultsType(String resultsType) { this.resultsType = resultsType; } public Set<org.openqa.selenium.Cookie> getSeleniumCookies() { return seleniumCookies; } public void setSeleniumCookies(Set<org.openqa.selenium.Cookie> cookies) { this.seleniumCookies = cookies; } public Map<String, String> getHeaders() { return headers; } public void setHeaders(Map<String, String> headers) { this.headers = headers; } /** * Checks the different results of a previous query to CSV file * * @param expectedResults A DataTable Object with all data needed for check the results. The DataTable must contains at least 2 columns: * a) A field column from the result * b) Occurrences column (Integer type) * <p> * Example: * |latitude| longitude|place |occurrences| * |12.5 |12.7 |Valencia |1 | * |2.5 | 2.6 |Stratio |0 | * |12.5 |13.7 |Sevilla |1 | * IMPORTANT: All columns must exist * @throws Exception exception */ public void resultsMustBeCSV(DataTable expectedResults) throws Exception { if (getCSVResults() != null) { //Map for cucumber expected results List<Map<String, Object>> resultsListExpected = new ArrayList<Map<String, Object>>(); Map<String, Object> resultsCucumber; for (int e = 1; e < expectedResults.getGherkinRows().size(); e++) { resultsCucumber = new HashMap<String, Object>(); for (int i = 0; i < expectedResults.getGherkinRows().get(0).getCells().size(); i++) { resultsCucumber.put(expectedResults.getGherkinRows().get(0).getCells().get(i), expectedResults.getGherkinRows().get(e).getCells().get(i)); } resultsListExpected.add(resultsCucumber); } getLogger().debug("Expected Results: " + resultsListExpected.toString()); getLogger().debug("Obtained Results: " + getCSVResults().toString()); //Comparisons int occurrencesObtained = 0; int iterations = 0; int occurrencesExpected = 0; String nextKey; for (int e = 0; e < resultsListExpected.size(); e++) { iterations = 0; occurrencesObtained = 0; occurrencesExpected = Integer.parseInt(resultsListExpected.get(e).get("occurrences").toString()); List<Map<String, String>> results = getCSVResults(); for (Map<String, String> result : results) { Iterator<String> it = resultsListExpected.get(0).keySet().iterator(); while (it.hasNext()) { nextKey = it.next(); if (!nextKey.equals("occurrences")) { if (result.get(nextKey).toString() .equals(resultsListExpected.get(e).get(nextKey).toString())) { iterations++; } } if (iterations == resultsListExpected.get(0).keySet().size() - 1) { occurrencesObtained++; iterations = 0; } } iterations = 0; } assertThat(occurrencesExpected) .overridingErrorMessage("In row " + e + " have been found " + occurrencesObtained + " results and " + occurrencesExpected + " were expected") .isEqualTo(occurrencesObtained); } } else { throw new Exception("You must execute a query before trying to get results"); } } /** * Checks the different results of a previous query to Cassandra database * * @param expectedResults A DataTable Object with all data needed for check the results. The DataTable must contains at least 2 columns: * a) A field column from the result * b) Occurrences column (Integer type) * <p> * Example: * |latitude| longitude|place |occurrences| * |12.5 |12.7 |Valencia |1 | * |2.5 | 2.6 |Stratio |0 | * |12.5 |13.7 |Sevilla |1 | * IMPORTANT: All columns must exist * @throws Exception exception */ public void resultsMustBeCassandra(DataTable expectedResults) throws Exception { if (getCassandraResults() != null) { //Map for query results ColumnDefinitions columns = getCassandraResults().getColumnDefinitions(); List<Row> rows = getCassandraResults().all(); List<Map<String, Object>> resultsListObtained = new ArrayList<Map<String, Object>>(); Map<String, Object> results; for (int i = 0; i < rows.size(); i++) { results = new HashMap<String, Object>(); for (int e = 0; e < columns.size(); e++) { results.put(columns.getName(e), rows.get(i).getObject(e)); } resultsListObtained.add(results); } getLogger().debug("Results: " + resultsListObtained.toString()); //Map for cucumber expected results List<Map<String, Object>> resultsListExpected = new ArrayList<Map<String, Object>>(); Map<String, Object> resultsCucumber; for (int e = 1; e < expectedResults.getGherkinRows().size(); e++) { resultsCucumber = new HashMap<String, Object>(); for (int i = 0; i < expectedResults.getGherkinRows().get(0).getCells().size(); i++) { resultsCucumber.put(expectedResults.getGherkinRows().get(0).getCells().get(i), expectedResults.getGherkinRows().get(e).getCells().get(i)); } resultsListExpected.add(resultsCucumber); } getLogger().debug("Expected Results: " + resultsListExpected.toString()); //Comparisons int occurrencesObtained = 0; int iterations = 0; int occurrencesExpected = 0; String nextKey; for (int e = 0; e < resultsListExpected.size(); e++) { iterations = 0; occurrencesObtained = 0; occurrencesExpected = Integer.parseInt(resultsListExpected.get(e).get("occurrences").toString()); for (int i = 0; i < resultsListObtained.size(); i++) { Iterator<String> it = resultsListExpected.get(0).keySet().iterator(); while (it.hasNext()) { nextKey = it.next(); if (!nextKey.equals("occurrences")) { if (resultsListObtained.get(i).get(nextKey).toString() .equals(resultsListExpected.get(e).get(nextKey).toString())) { iterations++; } } if (iterations == resultsListExpected.get(0).keySet().size() - 1) { occurrencesObtained++; iterations = 0; } } iterations = 0; } assertThat(occurrencesExpected) .overridingErrorMessage("In row " + e + " have been found " + occurrencesObtained + " results and " + occurrencesExpected + " were expected") .isEqualTo(occurrencesObtained); } } else { throw new Exception("You must execute a query before trying to get results"); } } /** * Checks the different results of a previous query to Mongo database * * @param expectedResults A DataTable Object with all data needed for check the results. The DataTable must contains at least 2 columns: * a) A field column from the result * b) Occurrences column (Integer type) * <p> * Example: * |latitude| longitude|place |occurrences| * |12.5 |12.7 |Valencia |1 | * |2.5 | 2.6 |Stratio |0 | * |12.5 |13.7 |Sevilla |1 | * IMPORTANT: All columns must exist * @throws Exception exception */ public void resultsMustBeMongo(DataTable expectedResults) throws Exception { if (getMongoResults() != null) { //Map for cucumber expected results List<Map<String, Object>> resultsListExpected = new ArrayList<Map<String, Object>>(); Map<String, Object> resultsCucumber; for (int e = 1; e < expectedResults.getGherkinRows().size(); e++) { resultsCucumber = new HashMap<String, Object>(); for (int i = 0; i < expectedResults.getGherkinRows().get(0).getCells().size(); i++) { resultsCucumber.put(expectedResults.getGherkinRows().get(0).getCells().get(i), expectedResults.getGherkinRows().get(e).getCells().get(i)); } resultsListExpected.add(resultsCucumber); } getLogger().debug("Expected Results: " + resultsListExpected.toString()); //Comparisons int occurrencesObtained = 0; int iterations = 0; int occurrencesExpected = 0; String nextKey; for (int e = 0; e < resultsListExpected.size(); e++) { iterations = 0; occurrencesObtained = 0; occurrencesExpected = Integer.parseInt(resultsListExpected.get(e).get("occurrences").toString()); String resultsListObtained = "["; DBCursor cursor = getMongoResults(); while (cursor.hasNext()) { DBObject row = cursor.next(); resultsListObtained = resultsListObtained + row.toString(); if (cursor.hasNext()) { resultsListObtained = ", " + resultsListObtained; } Iterator<String> it = resultsListExpected.get(0).keySet().iterator(); while (it.hasNext()) { nextKey = it.next(); if (!nextKey.equals("occurrences")) { if (row.get(nextKey).toString() .equals(resultsListExpected.get(e).get(nextKey).toString())) { iterations++; } } if (iterations == resultsListExpected.get(0).keySet().size() - 1) { occurrencesObtained++; iterations = 0; } } iterations = 0; if (cursor.hasNext()) { resultsListObtained = resultsListObtained + ","; } } resultsListObtained = resultsListObtained + "]"; getLogger().debug("Results: " + resultsListObtained); assertThat(occurrencesExpected) .overridingErrorMessage("In row " + e + " have been found " + occurrencesObtained + " results and " + occurrencesExpected + " were expected") .isEqualTo(occurrencesObtained); } } else { throw new Exception("You must execute a query before trying to get results"); } } /** * Checks the different results of a previous query to Elasticsearch database * * @param expectedResults A DataTable Object with all data needed for check the results. The DataTable must contains at least 2 columns: * a) A field column from the result * b) Occurrences column (Integer type) * <p> * Example: * |latitude| longitude|place |occurrences| * |12.5 |12.7 |Valencia |1 | * |2.5 | 2.6 |Stratio |0 | * |12.5 |13.7 |Sevilla |1 | * IMPORTANT: All columns must exist * @throws Exception exception */ public void resultsMustBeElasticsearch(DataTable expectedResults) throws Exception { if (getElasticsearchResults() != null) { List<List<String>> expectedResultList = expectedResults.raw(); //Check size assertThat(expectedResultList.size() - 1) .overridingErrorMessage("Expected number of columns to be" + (expectedResultList.size() - 1) + "but was " + previousElasticsearchResults.size()) .isEqualTo(previousElasticsearchResults.size()); List<String> columnNames = expectedResultList.get(0); for (int i = 0; i < previousElasticsearchResults.size(); i++) { for (int j = 0; j < columnNames.size(); j++) { assertThat(expectedResultList.get(i + 1).get(j)) .overridingErrorMessage("In row " + i + "and " + "column " + j + "have " + "been " + "found " + expectedResultList.get(i + 1).get(j) + " results and " + previousElasticsearchResults.get(i).get(columnNames.get(j)).toString() + " were " + "expected") .isEqualTo(previousElasticsearchResults.get(i).get(columnNames.get(j)).toString()); } } } else { throw new Exception("You must execute a query before trying to get results"); } } /** * Runs a command locally * * @param command command used to be run locally */ public void runLocalCommand(String command) throws Exception { String result = ""; String line; Process p; try { p = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", command }); p.waitFor(); } catch (java.io.IOException e) { this.commandExitStatus = 1; this.commandResult = "Error"; return; } BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); while ((line = input.readLine()) != null) { result += line; } input.close(); this.commandResult = result; this.commandExitStatus = p.exitValue(); p.destroy(); if (p.isAlive()) { p.destroyForcibly(); } } public int getCommandExitStatus() { return commandExitStatus; } public void setCommandExitStatus(int commandExitStatus) { this.commandExitStatus = commandExitStatus; } public String getCommandResult() { return commandResult; } public void setCommandResult(String commandResult) { this.commandResult = commandResult; } public String getRestProtocol() { return restProtocol; } /** * Set the REST host. * * @param restProtocol api protocol "http or https" */ public void setRestProtocol(String restProtocol) { this.restProtocol = restProtocol; } public List<Cookie> getCookies() { return cookies; } public void setCookies(List<Cookie> cookies) { this.cookies = cookies; } /** * Parse jsonpath expression from a given string. * <p> * If the string is json we can obtain its keys using ~ symbol. * <p> * If position is not null and the result of jsonpath expression is an array, * then this function will return the element at the given position at the array. * <p> * If position is null, it will return the result of the jsonpath evaluation as string. * * @param jsonString string to be parsed * @param expr jsonpath expression * @param position position from a search result */ public String getJSONPathString(String jsonString, String expr, String position) { String value; if (expr.contains(".~")) { this.getLogger().debug("Expression referred to json keys"); Pattern pattern = Pattern.compile("^(.*?).~(.*?)$"); Matcher matcher = pattern.matcher(expr); String aux = null; String op = null; if (matcher.find()) { aux = matcher.group(1); op = matcher.group(2); } LinkedHashMap auxData = JsonPath.parse(jsonString).read(aux); JSONObject json = new JSONObject(auxData); List<String> keys = IteratorUtils.toList(json.keys()); List<String> stringKeys = new ArrayList<String>(); if (op.equals("")) { for (String key : keys) { stringKeys.add("\"" + key + "\""); } value = stringKeys.toString(); } else { Pattern patternOp = Pattern.compile("^\\[(-?\\d+)\\]$"); Matcher matcherOp = patternOp.matcher(op); Integer index = null; Boolean isNegative = false; if (matcherOp.find()) { if (matcherOp.group(1).contains("-")) { isNegative = true; } index = Integer.parseInt(matcherOp.group(1).replace("-", "")); } if (isNegative) { value = keys.get(keys.size() - index).toString(); } else { value = keys.get(index).toString(); } } } else { String result = JsonValue.readHjson(jsonString).toString(); Object data = JsonPath.parse(result).read(expr); if (position != null) { JSONArray jsonArray = new JSONArray(data.toString()); value = jsonArray.get(Integer.parseInt(position)).toString(); } else { if (data instanceof LinkedHashMap) { value = (new JSONObject((LinkedHashMap) data)).toString(); } else { value = data.toString(); } } } return value; } /** * Remove a subelement in a JsonPath * * @param jsonString String of the json * @param expr regex to be removed */ public String removeJSONPathElement(String jsonString, String expr) { Configuration conf = Configuration.builder().jsonProvider(new GsonJsonProvider()) .mappingProvider(new GsonMappingProvider()).build(); DocumentContext context = JsonPath.using(conf).parse(jsonString); context.delete(expr); return context.jsonString(); } /** * The function searches over the array by certain field value, * and replaces occurences with the parameter provided. * * @param jsonString Original json object * @param key Key to search * @param value Value to replace key with */ public String replaceJSONPathElement(String jsonString, String key, String value) { return JsonPath.parse(jsonString).set(key, value).jsonString(); } /** * Evaluate an expression. * <p> * Object o could be a string or a list. * * @param o object to be evaluated * @param condition condition to compare * @param result expected result */ public void evaluateJSONElementOperation(Object o, String condition, String result) throws Exception { if (o instanceof String) { String value = (String) o; switch (condition) { case "equal": assertThat(value).as("Evaluate JSONPath does not match with proposed value").isEqualTo(result); break; case "not equal": assertThat(value).as("Evaluate JSONPath match with proposed value").isNotEqualTo(result); break; case "contains": assertThat(value).as("Evaluate JSONPath does not contain proposed value").contains(result); break; case "does not contain": assertThat(value).as("Evaluate JSONPath contain proposed value").doesNotContain(result); break; case "size": JsonValue jsonObject = JsonValue.readHjson(value); if (jsonObject.isArray()) { assertThat(jsonObject.asArray()).as("Keys size does not match") .hasSize(Integer.parseInt(result)); } else { Assertions.fail("Expected array for size operation check"); } break; default: Assertions.fail("Not implemented condition"); break; } } else if (o instanceof List) { List<String> keys = (List<String>) o; switch (condition) { case "contains": assertThat(keys).as("Keys does not contain that name").contains(result); break; case "size": assertThat(keys).as("Keys size does not match").hasSize(Integer.parseInt(result)); break; default: Assertions.fail("Operation not implemented for JSON keys"); } } } public ZookeeperSecUtils getZkSecClient() { return zkSecClient; } public void runCommandAndGetResult(String command) throws Exception { getRemoteSSHConnection().runCommand(command); setCommandResult(getRemoteSSHConnection().getResult()); } public String updateMarathonJson(String json) { return removeJSONPathElement(removeJSONPathElement(removeJSONPathElement(json, ".versionInfo"), ".version"), ".uris.*"); } public void runCommandLoggerAndEnvVar(int exitStatus, String envVar, Boolean local) { List<String> logOutput = Arrays.asList(this.getCommandResult().split("\n")); StringBuffer log = new StringBuffer(); int logLastLines = 25; if (logOutput.size() < 25) { logLastLines = logOutput.size(); } for (String s : logOutput.subList(logOutput.size() - logLastLines, logOutput.size())) { log.append(s).append("\n"); } if (envVar != null) { if (this.getRemoteSSHConnection() != null && !local) { ThreadProperty.set(envVar, this.getRemoteSSHConnection().getResult().trim()); } else { ThreadProperty.set(envVar, this.getCommandResult().trim()); } } if (this.getCommandExitStatus() != exitStatus) { if (System.getProperty("logLevel", "") != null && System.getProperty("logLevel", "").equalsIgnoreCase("debug")) { if (!("".equals(this.getCommandResult()))) { this.getLogger().debug("Command complete stdout:\n{}", this.getCommandResult()); } } else { this.getLogger().error("Command last {} lines stdout:", logLastLines); this.getLogger().error("{}", log); } } else { if (!("".equals(this.getCommandResult()))) { this.getLogger().debug("Command complete stdout:\n{}", this.getCommandResult()); } } } }