use of com.axway.ats.agent.core.templateactions.model.objects.ActionParser in project ats-framework by Axway.
the class TemplateActionMethod method doInvoke.
/**
* Invoke action and if needed return requested XPath entries as String[][]
*
*/
@Override
protected Object doInvoke(Object instance, List<String> parameterNames, Object[] parameterValues) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, ActionExecutionException {
if (log.isDebugEnabled()) {
log.debug("Executing '" + actionName + "' with arguments " + StringUtils.methodInputArgumentsToString(parameterValues));
}
TemplateActionsResponseVerificationConfigurator responseVerificationConfigurator = (TemplateActionsResponseVerificationConfigurator) ThreadContext.getAttribute(ThreadContext.TEMPLATE_ACTION_VERIFICATION_CONFIGURATOR);
String actionsXml = getActionsXml();
// insert any customer parameters into the thread scope map
for (int iParameter = 0; iParameter < parameterNames.size(); iParameter++) {
Object value = parameterValues[iParameter];
// if the value is an object with more than one values, add them in a Queue
if (value != null && (value instanceof Iterable || value.getClass().isArray())) {
Queue<Object> queue = new LinkedList<Object>();
if (value instanceof Iterable) {
for (Object oneValue : (Iterable<?>) value) {
queue.add(oneValue);
}
} else {
for (Object oneValue : (Object[]) value) {
queue.add(oneValue);
}
}
value = queue;
}
ThreadContext.setAttribute(parameterNames.get(iParameter), value);
}
long actionStartTimestamp = -1;
long totalTimeOfAllActionStepsNet = 0;
long totalTimeOfAllActionStepsBetweenReqAndResp = 0;
Object objectToReturn = null;
String checkpointName;
if (AbstractActionTask.REGISTER_FULL_AND_NET_ACTION_TIME_FOR_TEMPLATE_ACTIONS) {
checkpointName = actionName + "-net";
} else {
checkpointName = actionName;
}
try {
log.info("START running template actions from " + actionsXml);
actionStartTimestamp = System.currentTimeMillis();
if (isRegisterActionExecution() && !isLoggingInBatchMode) {
autoLogger.startCheckpoint(checkpointName, "", actionStartTimestamp);
}
XmlReader xmlReader = new XmlReader(actionsXml);
XmlUtilities xmlUtilities = new XmlUtilities();
long xmlParsingTime = System.currentTimeMillis() - actionStartTimestamp;
// this is the actual Action start time, skipping the actionXML parsing time
actionStartTimestamp += xmlParsingTime;
int actionNum = 1;
long currentTimeOfActionStepRequest;
NetworkingStopWatch stopWatch = new NetworkingStopWatch(actionMethodName);
while (xmlReader.goToNextAction()) {
String actionStep = actionMethodName + "[" + actionNum + "]";
stopWatch.step0_SetNewContext(actionStep);
String httpUrl = xmlReader.getRequestHttpUrl();
String httpMethod = xmlReader.getRequestHttpMethod();
List<ActionHeader> httpHeaders = xmlReader.getRequestHttpHeaders();
// connect to the specified URL
HttpClient httpClient = new HttpClient(httpUrl, httpMethod, httpHeaders, stopWatch);
// send HTTP request
String fileToSend = xmlReader.getRequestResourceFile();
httpClient.sendHttpRequest(actionStep, fileToSend, xmlReader.hasParamsInRequestResourceFile());
currentTimeOfActionStepRequest = stopWatch.getNetworkingTime();
// Measure and log time between last data sent and start of receive.
// Thread could be suspended but this could be server processing time too.
// and log request time
stopWatch.step5_StartInterimTimer();
// read response
ActionResponseObject expectedHttpResponseNode = xmlReader.getResponse();
// httpClient.disconnect(); // TODO: why this is needed. This is also before getting response
if (xmlReader.isLastAction() && (wantedXpathEntries != null || returnResponseBodyAsString)) {
if (returnResponseBodyAsString) {
// this is the last action and user wants to extract the response content as string
ActionParser actualHttpResponse = xmlUtilities.readActionResponse(httpClient, actionsXml, actionNum, true);
String contentAsString = actualHttpResponse.getBodyContentAsString();
actualHttpResponse.cleanupMembers();
objectToReturn = contentAsString;
// log response time below and after that return result
} else {
// this is the last action and user wants to extract some data from the response
ActionParser actualHttpResponse = xmlUtilities.readActionResponse(httpClient, actionsXml, actionNum, false);
String[][] extractedXpathEntries = XmlUtilities.extractXpathEntries(null, wantedXpathEntries);
actualHttpResponse.cleanupMembers();
objectToReturn = extractedXpathEntries;
// log response time below and after that return result
}
} else {
// verify the received response
xmlUtilities.verifyResponse(actionsXml, actionMethodName, actionNum, expectedHttpResponseNode, httpClient, responseVerificationConfigurator);
}
long currentTimeOfActionStepEnd = stopWatch.getNetworkingTime();
totalTimeOfAllActionStepsNet += currentTimeOfActionStepEnd;
totalTimeOfAllActionStepsBetweenReqAndResp += stopWatch.getTimeBetweenReqAndResponse();
if (HttpClient.logTimer.isTraceEnabled()) {
HttpClient.logTimer.trace("This action step " + actionStep + " time between end of send request and start of getting response time took " + stopWatch.getTimeBetweenReqAndResponse() + " ms");
HttpClient.logTimer.trace("This action step " + actionStep + " response network time took " + (currentTimeOfActionStepEnd - currentTimeOfActionStepRequest) + " ms");
HttpClient.logTimer.trace("This action step " + actionStep + " total network time took " + currentTimeOfActionStepEnd + " ms");
}
actionNum++;
}
if (isRegisterActionExecution()) {
if (HttpClient.logTimer.isTraceEnabled()) {
HttpClient.logTimer.trace("\t Total net time: " + totalTimeOfAllActionStepsNet + "(action " + actionsXml + ")| actionStartTimestamp : " + (actionStartTimestamp - xmlParsingTime) + "| total time between Req and Resp: " + totalTimeOfAllActionStepsBetweenReqAndResp);
}
if (isLoggingInBatchMode) {
autoLogger.insertCheckpoint(checkpointName, actionStartTimestamp - xmlParsingTime, totalTimeOfAllActionStepsNet, 0L, /* transferSize */
"", /* unit name */
CheckpointResult.PASSED);
} else {
autoLogger.endCheckpoint(checkpointName, 0L, /* transferSize */
CheckpointResult.PASSED, actionStartTimestamp - xmlParsingTime + /* the XML parsing time was previously added to the actionStartTimestamp (but after starting the Checkpoint) */
totalTimeOfAllActionStepsNet);
}
}
log.info("COMPLETE running template actions from " + actionsXml);
} catch (Exception e) {
if (isRegisterActionExecution()) {
if (isLoggingInBatchMode) {
autoLogger.insertCheckpoint(checkpointName, 0L, /* response time */
CheckpointResult.FAILED);
} else {
autoLogger.endCheckpoint(checkpointName, 0L, /* transfer size */
CheckpointResult.FAILED);
}
}
throw new ActionExecutionException("Error executing a template action", e);
}
if (AbstractActionTask.REGISTER_FULL_AND_NET_ACTION_TIME_FOR_TEMPLATE_ACTIONS) {
// Time between end of request and start of response reading - could be enabled only for some detailed investigations
autoLogger.insertCheckpoint(actionName + "-betweenReqAndResp", actionStartTimestamp, totalTimeOfAllActionStepsBetweenReqAndResp, 0L, null, CheckpointResult.PASSED);
}
return new CompositeResult(objectToReturn, totalTimeOfAllActionStepsNet);
}
use of com.axway.ats.agent.core.templateactions.model.objects.ActionParser in project ats-framework by Axway.
the class Test_XmlUtilities method verifyContentLengthZero.
@SuppressWarnings("serial")
@Test
public void verifyContentLengthZero() throws Exception {
String actionsXmlFileNameWoPath = "verifyContentLengthZero.xml";
String actionsXml = TEST_ACTIONS_HOME + actionsXmlFileNameWoPath;
XmlReader xmlReader = new XmlReader(actionsXml);
// non-zero content
xmlReader.goToNextAction();
// empty body of the response/content
xmlReader.goToNextAction();
TemplateActionsResponseVerificationConfigurator verificationConfigurator = new TemplateActionsResponseVerificationConfigurator("queue name");
// add globally applicable header matchers
final HeaderMatcher globalContentRange = new HeaderMatcher("Content-Length", "100", TemplateHeaderMatchMode.RANGE_OFFSET);
verificationConfigurator.addGlobalHeaderMatchers(new HashSet<HeaderMatcher>() {
{
add(globalContentRange);
}
});
resolveActionName(false);
// construct the fake client
MockHttpURLConnection mockHttpURLConnection = new MockHttpURLConnection();
mockHttpURLConnection.setFakeInputStream(TEST_ACTIONS_HOME, actionName + "_response.bin");
mockHttpURLConnection.setFakeContentType("text/html");
//mockHttpURLConnection.setFakeContentEncoding( contentEncoding );
HttpClient client = Test_HttpClient.getHttpClient(mockHttpURLConnection);
// add some headers
Map<String, List<String>> fakeHeaderFields = new HashMap<String, List<String>>();
List<String> acceptCharset = new ArrayList<String>();
acceptCharset.add("ISO-8859-1,utf-8;q=0.7,*;q=0.7");
fakeHeaderFields.put("Accept-Charset", acceptCharset);
// Content-Length header
List<String> contentLength = new ArrayList<String>();
contentLength.add("0");
fakeHeaderFields.put("Content-Length", contentLength);
fakeHeaderFields.put("Content-Type", new LinkedList<String>() {
{
add("text/html");
}
});
fakeHeaderFields.put("Accept-Ranges", new LinkedList<String>() {
{
add("bytes");
}
});
fakeHeaderFields.put("Server", new LinkedList<String>() {
{
add("Apache-Coyote/1.1");
}
});
// Status header
List<String> responseStatusHeaders = new ArrayList<String>();
responseStatusHeaders.add("HTTP/1.1 200 OK");
fakeHeaderFields.put(null, responseStatusHeaders);
mockHttpURLConnection.setFakeHeaderFields(fakeHeaderFields);
XmlUtilities xmlUtilities = new XmlUtilities();
ActionParser actionParser = xmlUtilities.readActionResponse(client, getDownloadsFolder() + actionName + ".xml", 1, false);
Node actualResponseNode = actionParser.getActionNodeWithoutBody();
String actualResponse = xmlUtilities.xmlNodeToString(actualResponseNode);
actualResponse = actualResponse.replace("<HTTP_RESPONSE>", "").replace("</HTTP_RESPONSE>", "").trim();
String expectedResponse = readFileLineByLine(TEST_ACTIONS_HOME + actionName + "_response.xml");
verifyResponseMatch(expectedResponse, actualResponse, "response body", "response bodies");
// Verify against HeaderMatchers
XmlUtilities utils = new XmlUtilities();
// Output directory for actual response bodies. Ending ".xml" is removed in verifyResponse
String outDirNamePathWithDotXML = getDownloadsFolder() + AtsSystemProperties.SYSTEM_FILE_SEPARATOR + actionsXmlFileNameWoPath;
// reset the stop watch interim state - just before reading response
client.getNetworkingStopWatch().step0_SetNewContext(actionsXmlFileNameWoPath);
client.getNetworkingStopWatch().setStateFromBeforeStep1ToAfterStep4();
client.getNetworkingStopWatch().step5_StartInterimTimer();
utils.verifyResponse(outDirNamePathWithDotXML, "verifyContentLengthZero", 1, xmlReader.getResponse(), client, verificationConfigurator);
}
use of com.axway.ats.agent.core.templateactions.model.objects.ActionParser in project ats-framework by Axway.
the class XmlUtilities method verifyResponse.
/**
* Verify the expected and actual responses match
*
* @param expectedHttpResponseObject
* @param currentActionRequestNumber current request/response step in this action/xml (starts from 1)
* @throws Exception
*/
public void verifyResponse(String actionsXml, String actionName, int currentActionRequestNumber, ActionResponseObject expectedHttpResponseObject, HttpClient httpClient, TemplateActionsResponseVerificationConfigurator responseVerificationConfigurator) throws Exception {
ActionParser actualHttpResponse = readActionResponse(httpClient, actionsXml, currentActionRequestNumber, false);
if (HttpClient.log.isTraceEnabled()) {
String causeMsg = "Print response for debugging purposes";
logActualResponse(causeMsg, actionName, currentActionRequestNumber, actualHttpResponse, false);
}
// stepMatchers now are after reading response so not to influence StopWatches
// list with all body matchers
List<ResponseMatcher> stepMatchers = new ArrayList<ResponseMatcher>();
// add all matchers from the XML file
List<XPathBodyMatcher> xpathBodyMatchers = applyUserParameters(expectedHttpResponseObject.getXpathBodyMatchers());
stepMatchers.addAll(xpathBodyMatchers);
// add all matchers from the test case
TemplateActionResponseVerificator responseVerificator = responseVerificationConfigurator.getActionVerificator(actionName);
if (responseVerificator != null) {
// there is a verificator for this action
stepMatchers.addAll(responseVerificator.getStepBodyMatchers(currentActionRequestNumber));
}
try {
// Compare HTTP response code
String expectedResponseResult = expectedHttpResponseObject.getResponseResult();
String actualResponseResult = getFirstChildNode(actualHttpResponse.getActionNodeWithoutBody(), TOKEN_HTTP_RESPONSE_RESULT).getTextContent();
if (!expectedResponseResult.equalsIgnoreCase(actualResponseResult)) {
String causeMsg = "Expected response result '" + expectedResponseResult + "' is different than the actual '" + actualResponseResult + "'.";
logActualResponse(causeMsg, actionName, currentActionRequestNumber, actualHttpResponse, true);
throw new XmlUtilitiesException(causeMsg);
}
// Compare response headers. It extracts any user parameters if present in the headers.
verifyResponseHeaders(actionName, currentActionRequestNumber, expectedHttpResponseObject.getHttpHeaderMatchers(), actualHttpResponse, responseVerificationConfigurator);
// Compare response files
verifyResponseFile(expectedHttpResponseObject, actualHttpResponse.getActionNodeWithoutBody());
if (!stepMatchers.isEmpty()) {
// TODO verify the response body here
}
} finally {
actualHttpResponse.cleanupMembers();
}
log.info(actionName + "[" + currentActionRequestNumber + "] -> " + "Verified HTTP response");
}
use of com.axway.ats.agent.core.templateactions.model.objects.ActionParser in project ats-framework by Axway.
the class XmlUtilities method readActionResponse.
/**
*
* @param HttpClient httpClient
* @param actionsXml full name (with path) of the actions file. Used for generating relative paths for body contents
* @param actionNum action number among all ones in the file
* @param saveResponseBodyBytes whether to save the response body bytes even the resource file content
* @return XML Node with parsed HTTP response
* @throws Exception
*/
public ActionParser readActionResponse(HttpClient httpClient, String actionsXml, int actionNum, boolean saveResponseBodyBytes) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.newDocument();
Node httpActions = dom.createElement(TOKEN_HTTP_ACTIONS);
dom.appendChild(httpActions);
Node httpAction = dom.createElement(TOKEN_HTTP_ACTION);
httpActions.appendChild(httpAction);
Node actualResponseWithoutBodyNode = dom.createElement(TOKEN_HTTP_RESPONSE);
httpAction.appendChild(actualResponseWithoutBodyNode);
// read connection input stream bytes
int contentLength = 0;
byte[] responseBodyBytes = null;
int responseCode = -1;
httpClient.getNetworkingStopWatch().step6_StartGetResponseCode();
// this effectively may send request and wait for response
responseCode = httpClient.getUrlConnection().getResponseCode();
httpClient.getNetworkingStopWatch().step7_EndGetResponseCode();
if (httpClient.getUrlConnection().getDoInput() && // if the response code is "302 Found" we assume that the response body is empty
responseCode != 302) {
// save the retrieved file
Node resourceFileNode = httpClient.httpBodyToXml(dom, actionsXml, actionNum, saveResponseBodyBytes);
if (httpClient.getResponseBodyBytes() != null) {
// for disc write or error logging
responseBodyBytes = httpClient.getResponseBodyBytes();
}
if (resourceFileNode != null) {
actualResponseWithoutBodyNode.appendChild(resourceFileNode);
if (((Element) resourceFileNode).hasAttribute("size")) {
contentLength = Integer.parseInt(((Element) resourceFileNode).getAttribute("size"));
}
}
}
// add headers
actualResponseWithoutBodyNode = httpClient.readHeaders(dom, actualResponseWithoutBodyNode, contentLength);
ActionParser actionResponse = new ActionParser(actualResponseWithoutBodyNode, responseBodyBytes);
actionResponse.setContentType(httpClient.getUrlConnection().getContentType());
return actionResponse;
}
use of com.axway.ats.agent.core.templateactions.model.objects.ActionParser in project ats-framework by Axway.
the class Test_HttpClient method testHeaders.
@Test
public void testHeaders() throws Exception {
resolveActionName(false);
// construct the fake client
MockHttpURLConnection mockHttpURLConnection = new MockHttpURLConnection();
mockHttpURLConnection.setFakeInputStream(TEST_ACTIONS_HOME, actionName + "_response.bin");
mockHttpURLConnection.setFakeContentType("text/javascript");
// add some headers
Map<String, List<String>> fakeHeaderFields = new HashMap<String, List<String>>();
// User-Agent header
List<String> userAgentHeaders = new ArrayList<String>();
userAgentHeaders.add("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3");
fakeHeaderFields.put("User-Agent", userAgentHeaders);
// Accept-Charset header
List<String> acceptCharset = new ArrayList<String>();
acceptCharset.add("ISO-8859-1,utf-8;q=0.7,*;q=0.7");
fakeHeaderFields.put("Accept-Charset", acceptCharset);
// Content-Length header
List<String> contentLength = new ArrayList<String>();
contentLength.add("541");
fakeHeaderFields.put("Content-Length", contentLength);
// Status header
List<String> responseStatusHeaders = new ArrayList<String>();
responseStatusHeaders.add("200 OK");
fakeHeaderFields.put(null, responseStatusHeaders);
mockHttpURLConnection.setFakeHeaderFields(fakeHeaderFields);
HttpClient client = getHttpClient(mockHttpURLConnection);
XmlUtilities xmlUtilities = new XmlUtilities();
String downloadsFolder = getDownloadsFolder();
ActionParser actionParser = xmlUtilities.readActionResponse(client, downloadsFolder + actionName + ".xml", 1, false);
Node actualResponseNode = actionParser.getActionNodeWithoutBody();
String actualResponseBody = xmlUtilities.xmlNodeToString(actualResponseNode);
String expectedResponseBody = readFileLineByLine(TEST_ACTIONS_HOME + actionName + "_response.xml");
verifyResponseMatch(expectedResponseBody, actualResponseBody, "response body", "response bodies");
}
Aggregations