Jmeter xpath extractor not giving node value for valid Xpath - javascript

I am using Xpath Extractor to find out a node value from a XML response but Jmeter is throwing an error every time I execute with the following error:
jmeter.extractor.XPathExtractor: TransformerException while processing
((//*[local-name() = 'RequestID'])[2]/text()) -1
The xpath expression used in Jmeter: (//*[local-name() = 'RequestID'])[2]/text()
I checked my xpath expression online and its valid and returning the expected value. Not sure what is the problem with jmeter.
Here is the xml:
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<urn1:ServiceControl xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">
<urn1:EmergencyRequestIndicator>true</urn1:EmergencyRequestIndicator>
<urn1:VersionID>1.0</urn1:VersionID>
<urn1:LanguageCode type="Advisor">en-US</urn1:LanguageCode>
<urn1:LanguageCode type="Subscriber">en-US</urn1:LanguageCode>
<urn1:ApplicationID>GAA</urn1:ApplicationID>
<urn1:LogicalID>W2DZD0Y06</urn1:LogicalID>
<urn1:ComponentID>GAA-ocsComponent</urn1:ComponentID>
<urn1:ReferenceID>CorrelationId</urn1:ReferenceID>
<urn1:SentTimeStamp>2010-04-23T14:27:10Z</urn1:SentTimeStamp>
<urn1:MessageType>ocsMessageType</urn1:MessageType>
<urn1:ChannelID>GAA</urn1:ChannelID>
<urn1:TaskID>ocsTask</urn1:TaskID>
<urn1:Environment>4.0</urn1:Environment>
<urn1:BODID>GAA-CorrelationId</urn1:BODID>
<urn1:Asynchronous>
<urn1:TimeToLive xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">10</urn1:TimeToLive>
<urn1:PassThroughData xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">
<urn1:Key xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">1</urn1:Key>
<urn1:Value xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">10</urn1:Value>
</urn1:PassThroughData>
<urn1:ExpectedResponseTime xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">30</urn1:ExpectedResponseTime>
<urn1:RequestID xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">100</urn1:RequestID>
<urn1:RetryStrategy xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">
<urn1:Name xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">RetryName</urn1:Name>
<urn1:LongTermRetryIndicator xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">false</urn1:LongTermRetryIndicator>
<urn1:ResponseRequiredOnErrorPoolMoveIndicator xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">true</urn1:ResponseRequiredOnErrorPoolMoveIndicator>
</urn1:RetryStrategy>
<urn1:ReplyRequiredIndicator xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">true</urn1:ReplyRequiredIndicator>
<urn1:ReplyToMessageID xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">1000</urn1:ReplyToMessageID>
<urn1:CallbackURI xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">urn1:www:com</urn1:CallbackURI>
<urn1:FaultURI xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">urn1:www:com</urn1:FaultURI>
<urn1:ProcessingModes xmlns:urn1="urn:com:sample:global:common:schema:ServiceControl:2">ProcessingMode</urn1:ProcessingModes>
</urn1:Asynchronous>
<urn1:Synchronous/>
</urn1:ServiceControl>
</S:Header>
<S:Body>
<ns2:ServiceRequestReference xmlns="urn:com:sample:ocs:common:schema:AutoTask:11" xmlns:ns10="urn:com:sample:global:common:schema:CallContext:2" xmlns:ns11="urn:com:sample:ocs:common:schema:ServiceFault:11" xmlns:ns12="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns13="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns14="http://www.w3.org/2000/09/xmldsig#" xmlns:ns15="urn:com:sample:global:common:schema:ServiceControl:2" xmlns:ns2="urn:com:sample:ocs:common:schema:CommonTypes:11" xmlns:ns3="urn:com:sample:ocs:common:schema:AutoInformation:11" xmlns:ns4="urn:com:sample:ocs:common:schema:UnitConfiguration:11" xmlns:ns5="urn:com:sample:ocs:common:schema:SubscriberRequest:11" xmlns:ns6="urn:com:sample:ocs:common:schema:ElectricAuto:11" xmlns:ns7="urn:com:sample:ocs:common:schema:EmergencyRequest:11" xmlns:ns8="urn:com:sample:ocs:common:schema:AutoRequest:11" xmlns:ns9="urn:com:sample:ocs:common:schema:AutoConnection:11">
<ns2:RequestID>2648331</ns2:RequestID>
<ns2:isProcessingAnotherRequest>false</ns2:isProcessingAnotherRequest>
<ns2:estimatedProcessingTime>0</ns2:estimatedProcessingTime>
</ns2:ServiceRequestReference>
</S:Body>
</S:Envelope>

You can subtract 1 from variable using i.e. Beanshell Post Processor
Assuming that you use RequestID as a reference name in XPath Extractor and following XPath is being used to get RequestID
(//*[local-name() = 'RequestID'])[2]/text()
or
//ns2:RequestID/text()
Next Beanshell code will allow you to manipulate the variable
int requestId = Integer.parseInt(vars.get("RequestID"));
requestId = requestId--;
vars.put("RequestID", String.valueOf(requestId));

Related

How do I generate digest value in SOAP signature

I'm try to generate the digest value for a Soap signing, let me explain it
I have the following xml signature (this should be my result)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:srv="...">
<soapenv:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Timestamp wsu:Id="TS-A9D96CB86647A0D4FC1673631078676136">
<wsu:Created>2023-02-02T19:11:30.780Z</wsu:Created>
<wsu:Expires>2023-02-02T19:12:00.780Z</wsu:Expires>
</wsu:Timestamp>
<ds:Signature Id="SIG-14C9D524EF6E12B1C61675365090921410" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="soapenv srv" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#TS-A9D96CB86647A0D4FC1673631078676136">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces PrefixList="wsse soapenv srv" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<ds:DigestValue>7UyPvxTBuetBFmJ3rLhKWwUDadF2vsPYMeVsvl5WS5E=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
[...]
</ds:Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body></soapenv:Body>
</soapenv:Envelope>
I trying to generate this, using the Timestamp
<ds:DigestValue>7UyPvxTBuetBFmJ3rLhKWwUDadF2vsPYMeVsvl5WS5E=</ds:DigestValue>
I know the following:
I need to sign the timestamp (Element, not content)
I need to use RSA-SHA1 with my RSA private key
Apply SHA256 to the result, and finally convert it to BASE64
<wsu:Timestamp wsu:Id="TS-A9D96CB86647A0D4FC1673631078676136">
<wsu:Created>2023-02-02T19:11:30.780Z</wsu:Created>
<wsu:Expires>2023-02-02T19:12:00.780Z</wsu:Expires>
</wsu:Timestamp>
but when I send it, the server responds the following
Signature verification failed: Core validity=false Signed info validity=false Signed info
message='SignatureValue mismatched.' Ref[0](validity=false message='Digest value mismatch:
calculated: bD55KG25aJxqkvQBe/ZTK1oYEafW3gfyf7okFy40yF0='
uri='#TS-A9D96CB86647A0D4FC1673631078676136' type='null')
Does anyone know how I have to encrypt this content? I read somewhere that I need to apply 'xml-exc-c14n' canonicalization, it's correct? How would the result be after apply the canonicalization?
PD. This is my function to test, I'm using javascript
function encryptRsaSha1(privateKey) {
const message = `<wsu:Timestamp wsu:Id="TS-A9D96CB86647A0D4FC1673631078676136">
<wsu:Created>2023-02-02T19:11:30.780Z</wsu:Created>
<wsu:Expires>2023-02-02T19:12:00.780Z</wsu:Expires>
</wsu:Timestamp>`
const sign = crypto.createSign('RSA-SHA1');
sign.update(message.replace(/\n/g, ''));
sign.end();
const signature = sign.sign(privateKey);
const hash = crypto.createHash('sha256').update(signature).digest('base64');
console.log("Signature: ", hash);
return hash
}
Thanks!
I tried to sign the content in different way, with/without new lines, with/without namespaces, the element, the content, etc.

Using a variable in Python selenium XPATH

I have a variable as follows:
client_Id = driver.execute_script("return getCurrentClientId()")
I am trying to replace the last value in the XPATH (after clientid=2227885) i.e.2227885 with the variable client_Id. So:
prog_note = wait.until(EC.presence_of_element_located((By.XPATH, "//a[#href='/admin/client/cp_progressnotes.jsp?ESOLclientid=2227885']")))
Should have the number component, in this case, 2227885 replaced with client_Id variable.
How could I go about this? I tried the following to no success
prog_note = wait.until(EC.presence_of_element_located((By.XPATH, "//a[contains(#href, 'cp_progressnotes', "+client_Id + "')]")))
xppath = "//a[#href='/admin/client/cp_progressnotes.jsp?ESOLclientid={}']".format(client_Id )
prog_note = wait.until(EC.presence_of_element_located((By.XPATH, xpath)))
use format

How to save XML file as .xml which is output from SQL Server in Java?

I want to run SQL query in Java and the result of the query is in xml. The query result is as follows -
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Rows>
<Unique_id>6124</Unique_id>
<DoorNo>12</DoorNo>
<StreetNo>1</StreetNo>
<SiteNo>84904</SiteNo>
</Rows>
<Rows>
<Unique_id>6125</Unique_id>
<DoorNo>12</DoorNo>
<StreetNo>2</StreetNo>
<SiteNo>84904</SiteNo>
</Rows>
</Root>
Now I want to export the above xml into an external file called QueryResult.xml using java.
I have tried using the below java script but unable to save the file.
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con=DriverManager.getConnection("jdbc:sqlserver://sqldatabase:1009;
databaseName=DatabaseName;user=UserName;password=1234");
PreparedStatement ps=con.prepareStatement(QueryName);
ResultSet rs=ps.executeQuery();
SQLXML xmlVal1= rs.getSQLXML(1);
String val = xmlVal1.getString();
try (PrintWriter out = new PrintWriter(new File("Output.xml"))) {
out.println(val);
}
Query Name:
select Distinct Unique_id, DoorNo, StreetNo, Siteno from Table Name where
Unqiue_id IN ( '6124','6125') FOR XML RAW ('Rows'), ROOT ('Root'), ELEMENTS XSINIL;
SQLXML xmlVal= rs.getSQLXML(1);
String val = xmlVal.getString();
try (PrintWriter out = new PrintWriter("out.xml")) {
out.println(val);
}
Here is the Oracle Tutorial with code examples.
Regarding your code,
1. you forgot to make next() on result set;
2. you don't need SQLXML here at all.
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con=DriverManager.getConnection("jdbc:sqlserver://sqldatabase:1009;
databaseName=DatabaseName;user=UserName;password=1234");
PreparedStatement ps=con.prepareStatement(QueryName);
ResultSet rs=ps.executeQuery();
rs.next();
String val = rs.getString(1);
try (PrintWriter out = new PrintWriter(new File("Output.xml"))) {
out.println(val);
}

Parsing a JSON sub string

I have javascript function that calls an external Api and returns in most case a valid JSON string.
function (successResponse) {
{
console.log(successResponse);
}
However, in some cases it return the the following invalid JSON
Response: Status=200, Text: {"createdTime":"2017-05-08T14:47:56Z","lastUpdatedTime":"2017-05-08T14:47:56Z","createdMode":"API","uuid":"e333c1-3599-36d7-9ef5-dc22c79a4a52","userId":"anonymous"}, Error Message: null
How can I parse the above string to get the 'uuid'
Thanks
If you're expecting a response string in that format, you can use a regular expression to extract the "text" portion of the response:
function (successResponse) {
{
var responseText = successResponse.match(/\{.+\}/);
var responseTextJSON = JSON.parse(responseText);
var uuid = responseTextJSON.uuid;
console.log(uuid);
}
Maybe you can parse the string yourself to exclude everything outside of {} ?
var apiResponse = 'Response: Status=200, Text: {"createdTime":"2017-05-08T14:47:56Z","lastUpdatedTime":"2017-05-08T14:47:56Z","createdMode":"API","uuid":"e333c1-3599-36d7-9ef5-dc22c79a4a52","userId":"anonymous"}, Error Message: null';
var apiResponse_fixed = apiResponse.substring((apiResponse.indexOf("{") - 1), (apiResponse.lastIndexOf("}") + 1));
var json_obj = JSON.parse(apiResponse_fixed);
console.log(json_obj.uuid);
Replace the non-JSON features, and then interpret as JSON
Looks like the server owner has been a bit lazy, and programmed an error response which contains a JSON-like interior section but surrounded by a couple of non-JSON elements.
If you are desperate to resolve the situation and have no ability to fix the server output format, here is my suggestion:
notQuiteJson = 'Response: Status=200, Text: {"createdTime":"2017-05-08T14:47:56Z","lastUpdatedTime":"2017-05-08T14:47:56Z","createdMode":"API","uuid":"e333c1-3599-36d7-9ef5-dc22c79a4a52","userId":"anonymous"}, Error Message: null';
madeJson = notQuiteJson.replace('Response: Status=200, Text:','{"Response": {"Status":200}, "Text":').replace('Error Message: null','"ErrorMessage": null}')
obj = JSON.parse(madeJson)
console.log(obj.Text.uuid) // Result: "e333c1-3599-36d7-9ef5-dc22c79a4a52"
Of course this only works if the error message is always exactly this. In reality you may want to use a 3-digit wildcard to cover a range of "Status=" codes. But then you would have to also be confident that all the error modes produce the same non-JSON text at the start and end of the response.
Disclaimer
#sp00m and #Bergi, don't kill me: you are right of course, but this is just for if the poster has no choice in the matter 8-)

Removing invalid characters from XML before serializing it with XMLSerializer()

I'm trying to store user-input in an XML document on the client-side (javascript), and transmit that to the server for persistence.
One user, for example, pasted in text that included an STX character (0x2). The XMLSerializer did not escape the STX character, and therefore, did not serialize to well-formed XML. Or perhaps the .attr() call should have escaped the STX character, but in either case, invalid XML was produced.
I'm finding the output of in-browser XMLSerializer() isn't always well-formed, (and doesn't even satisfy the browser's own DOMParser()
This example shows that the STX character is not properly encoded by XMLSerializer():
> doc = $.parseXML('<?xml version="1.0" encoding="utf-8" ?>\n<elem></elem>');
#document
> $(doc).find("elem").attr("someattr", String.fromCharCode(0x2));
[ <elem someattr=​"">​</elem>​ ]
> serializedDoc = new XMLSerializer().serializeToString(doc);
"<?xml version="1.0" encoding="utf-8"?><elem someattr=""/></elem>"
> $.parseXML(serializedDoc);
Error: Invalid XML: <?xml version="1.0" encoding="utf-8"?><elem someattr=""/></elem>
How should I construct an XML document in-browser (with params determined by arbitrary user-input) such that it will always be well-formed (everything properly escaped)? I don't need to support IE8 or IE7.
(And yes, I do validate the XML on the server side, but if the browser hands the server a document that is not well-formed, the best the server can do is reject it, which isn't that helpful to the poor user)
Here's a function sanitizeStringForXML() which can either be used to cleanse strings before assignment, or a derivative function removeInvalidCharacters(xmlNode) which can be passed a DOM tree and will automatically sanitize attributes and textNodes so they are safe to store.
var stringWithSTX = "Bad" + String.fromCharCode(2) + "News";
var xmlNode = $("<myelem/>").attr("badattr", stringWithSTX);
var serializer = new XMLSerializer();
var invalidXML = serializer.serializeToString(xmlNode);
// Now cleanse it:
removeInvalidCharacters(xmlNode);
var validXML = serializer.serializeToString(xmlNode);
I based this on a list of characters from the non-restricted characters section of this wikipedia article, but the supplementary planes require 5-hex-digit unicode characters, and the Javascript regex does not include a syntax for this, so for now, I'm just stripping them out (you aren't missing too much...):
// WARNING: too painful to include supplementary planes, these characters (0x10000 and higher)
// will be stripped by this function. See what you are missing (heiroglyphics, emoji, etc) at:
// http://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane
var NOT_SAFE_IN_XML_1_0 = /[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm;
function sanitizeStringForXML(theString) {
"use strict";
return theString.replace(NOT_SAFE_IN_XML_1_0, '');
}
function removeInvalidCharacters(node) {
"use strict";
if (node.attributes) {
for (var i = 0; i < node.attributes.length; i++) {
var attribute = node.attributes[i];
if (attribute.nodeValue) {
attribute.nodeValue = sanitizeStringForXML(attribute.nodeValue);
}
}
}
if (node.childNodes) {
for (var i = 0; i < node.childNodes.length; i++) {
var childNode = node.childNodes[i];
if (childNode.nodeType == 1 /* ELEMENT_NODE */) {
removeInvalidCharacters(childNode);
} else if (childNode.nodeType == 3 /* TEXT_NODE */) {
if (childNode.nodeValue) {
childNode.nodeValue = sanitizeStringForXML(childNode.nodeValue);
}
}
}
}
}
Note that this only removes invalid characters from nodeValues of attributes and textNodes. It does not check tag names or attribute names, comments, etc etc.
Check
https://gist.github.com/john-doherty/b9195065884cdbfd2017a4756e6409cc,
very useful gist, example usage:
const resultXml = removeXMLInvalidChars(INPUT_XML_STRING, true);

Categories

Resources