Spring EL - "There is still more data in the expression" - spring

Is it possible to parse an expression like the one shown below, where I call a method and would like to have text after the result of that method call?
String expression = "obj.someMethod()'test'";
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(expression);
When I run code like the one below I get the following error:
org.springframework.expression.spel.SpelParseException: EL1041E:(pos 23): After parsing a valid expression, there is still more data in the expression: 'test'
If I remove the 'test' string, then it parsers and evaluates correctly.

Even if it is Expression language it is based on the core programming language and follows with its rules.
So, if you use + operator to concat method result with the string in Java, you should do the same in SpEL:
"obj.someMethod() + 'test'"
is correct answer for you.
As well as you can use :
"obj.someMethod().concat('test')"
if someMethod() returns String, of course.

Related

Passing parameter to Match query in Neo4j using Spring

I am trying to compare node name from Neo4j database with given technology name. I am doing using Spring Application.
#Query("MATCH (n) WHERE n.name =~ '(?i){0}' RETURN n.name")
String getTechnology(String technologyname);
Request is like
MATCH (n)
WHERE n.name =~ '(?i){0}'
RETURN n.name
with params {0=AVM}.
But it's returning null. However, if I do it actual technology name it's working fine.
Pass the parameter as WHERE n.name =~ {0}. What's happening is that the parameter isn't substituted from within the string, so the parameter has no binding in the query, and instead you're searching for the string literal "{0}" which always fails.
If you want to pass a regex as a parameter, you'll need to put the "(?i)" part in the string getting passed, effectively letting your code decide the regex, not just a string inside of it.
You need to separate the regular expression part from the parameter part like this:
#Query("MATCH (n) WHERE n.name =~ '(?i)' + {0} RETURN n.name")
String getTechnology(String technologyname);
As You'd concatenate in Neo4j.

Parsing error on trying to retrieve value of a variable extracted using JSON path extractor in Jmeter

I have to assert JSON response of an API.
So extracted value of a field (state) using JSON path extractor and save it in variable (Optinurl)
"state":"opted_in"
In the Debug Sampler, i see the value of Optinurl as
Optinurl=
[
: "opted_in"
]
Optinurl_1=opted_in
Optinurl_matchNr=1
When i try to retrieve value of variable Optinurl in Beanshell assertion as below,
String optinValue = ${Optinurl}
i get
ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: String optinValue = '["opted_in"]';'' Token Parsing Error: Lexical error at line 1, column 23. Encountered: "\"" (34), after : "\'["
2016/03/07 14:40:15 WARN - jmeter.assertions.BeanShellAssertion: org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of:String optinValue = '["opted_in"]';'' Token Parsing Error: Lexical error at line 1, column 23. Encountered: "\"" (34), after : "\'["
Thanks for your help in advance !
There is a JSON Path Assertion available via JMeter Plugins project, I believe you can do what you need via it.
The correct ways of initializing a JMeter Variable in Beanshell are:
String optinValue = "${Optinurl}";
or
String optinValue = vars.get("Optinurl");
The error you're getting is not connected with your Optinurl variable initialization. Looking into
Lexical error at line 1, column 23.
It appears you have some syntax error in the very first script line. So the options are:
Double check your code, make sure that parentheses, quotation marks, etc. are matching, statements are ending with semicolon, quotation marks in strings are escaped, etc.
Adding debug(); line as the first line of your script produces comprehensive debug output to STDOUT
Surrounding your code into try/catch block allows to having more informative error stracktraces
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for more detailed information on using Beanshell in your JMeter tests.
I think you want to store [ : "opted_in" ] into a string variable so use this:
String optionValue= vars.get("Optinurl");
into your beanshell assertion
and if you want only opted_in to store in to a variable then use
String optionValue= vars.get("Optinurl_1");
Thanks Dmitri, Kaushlendra for replying.
I updated my script as below and it is working fine in GUI/command line. Since vars.get("Optinurl") returns ["opted_in"], so had to remove quotes and square brackets before comparing Strings.
String optinValue = vars.get("Optinurl"). replace("[","").replace("]","").replace("\"","");
String expectedState = "${EXPECTED_STATE}";
log.info(optinValue);
log.info(expectedState);
if(!optinValue.equals(expectedState)){
Failure = true;
FailureMessage = "Values of state field for Campaign id " + "${CAMPAIGN_ID}" + " dont match ";
}
I could not use String optinValue = vars.get("Optinurl_1") because it fails when i run tests from command line (works fine in GUI mode though)

Use Datasource Properties in XPath Expression of SoapUI

I need to know whether it is possible to use a datasource property in XPath Expression panel of XPath Match Configuration. For instance, if we have the following XML document:
<ns1:Ions>
<ns1:Ion>UI</ns1:Ion>
<ns1:IonType>X</ns1:IonType>
<ns1:StartDate>2010-05-10</ns1:StartDate>
</ns1:Ions>
<ns1:Ions>
<ns1:Ion>HH</ns1:Ion>
<ns1:IonType>RI</ns1:IonType>
<ns1:StartDate>1998-11-23</ns1:StartDate>
</ns1:Ions>
<ns1:Ions>
<ns1:Ion>CF</ns1:Ion>
<ns1:IonType>A</ns1:IonType>
<ns1:StartDate>2000-06-10</ns1:StartDate>
</ns1:Ions>
I need to evaluate to see whether a content of IonType is 'A' only if its sibling node, Ion, has a value of 'CF'. I was hoping to accomplish this by setting XPath Match Configuration as following:
XPath Expression (DataSourceInput#ION is 'CF')
declare namespace ns1='http://my.namespace.com';
//ns1:Ions[ns1:Ion[text()=${DataSourceInput#ION}]]/ns1:IonType/text()
Expected Results (DataSourceInput#ION_TYPE is 'A')
${DataSourceInput#ION_TYPE}
Running the test would result in SoapUI [Pro] to error the following, Missing content for xpath declare. If I replace ${DataSourceInput#ION} with an actual value, i.e. 'CF', the test works accordingly (I even tried place single quotes around ${DataSourceInput#ION}, but it didn't work).
Is there another way of accomplish this in SoapUI?
I try what you do and it works for me if I put single quotes around the property:
declare namespace ns1='http://my.namespace.com';
//ns1:Ions[ns1:Ion[text()='${DataSourceInput#ION}']]/ns1:IonType/text()
Did you check that testStep name is exactly DataSourceInput? If there are spaces in the TestStep name (i.e your testStep name is Data Source Input you have to put ${Data Source Input#ION}).
Anyway I give you another way to do so, you can add a testStep of type groovy script after the testStep where you are getting the <Ions>response, and check the assert here like follows:
// get xml holder
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
def ionsHolder = groovyUtils.getXmlHolder("IonsTestStepName#response");
// generate xpath expression
def xpathExpression = "//*:Ions[*:Ion[text()='" + context.expand('${DataSourceInput#ION}') + "']]/*:IonType/text()";
log.info xpathExpression;
// get the node value
def nodeValue = ionsHolder.getNodeValue(xpathExpression);
// check expected value
assert nodeValue == context.expand('${DataSourceInput#ION_TYPE}'),'ERROR IONS VALUE';
Hope this helps,

spring mongo creating like query

I can match starting of string i.e clo with keywords and it gives me correct result db.post.find({"keywords":"/^clo/"}).pretty() When I tried to write same query using spring mongo.It not working properly. It gives result as % string %. i.e. matches anywhere in string. I am trying to match only at starting . my code is
String pattern = "/^" + keyword + "/";
Criteria criteria2 = Criteria.where("keywords").is(keyword).regex(pattern);
Where I am missing ?
You can do it like this:
Query.query(Criteria.where("keywords").regex("^clo"))
Or use it as native query:
new BasicQuery("{'keywords' : '/^clo/'}")
Method is() provides the full equals, regex() has to be without / wrappers.
That's is your issue.

What is Ruby doing with gsub here?

I'm working on converting code from Ruby to Node.js. I came across these lines at the end of a function and I'm curious what the original developers were trying to accomplish:
url = url.gsub "member_id", "member_id__hashed"
url = url.gsub member_id, member_id_hashed
url
I'm assuming that url at the end is Ruby's equivalent to return url;
as for the lines with gsub, from what I've found online that's the wrong syntax, right? Shouldn't it be:
url = url.gsub(var1, var2)?
If it is correct, why are they calling it twice, once with quotes and once without?
gsub does a global substitute on a string. If I had to guess, the URL might be in the form of
http://somewebsite.com?member_id=123
If so, the code has the following effect:
url.gsub "member_id", "member_id__hashed"
# => "http://somewebsite.com?member_id__hashed=123"
Assuming member_id = "123", and member_id_hashed is some hashed version of the id, then the second line would replace "123" with the hashed version.
url.gsub member_id, member_id_hashed
# => "http://somewebsite.com?member_id__hashed=abc"
So you're going from http://somewebsite.com?member_id=123 to http://somewebsite.com?member_id__hashed=abc
Documentation: https://ruby-doc.org/core-2.6/String.html#method-i-gsub
I'm assuming that the url at the end is Ruby's equivalent to return url;
If that code is part of a method or block, indeed, the line url is the value returned by the method. This is because by default a method in Ruby returns the value of the last expression that was evaluated in the method. The keyword return can be used (as in many other languages) to produce an early return of a method, with or without a return value.
that's the wrong syntax, right? shouldn't it be
url = url.gsub(var1, var2)?
The arguments used to invoke a method in Ruby may stay in parentheses but they may, as well, be listed after the method name, without parentheses.
Both:
url = url.gsub var1, var2
and
url = url.gsub(var1, var2)
are correct and they produce the same result.
The convention in Ruby is to not put parentheses around method arguments but this is not always possible. One such case is when one of the arguments is a call of another method with arguments.
The parentheses are then used to make everything clear both for the interpreter and the readers of the code.
If it is correct, why are they calling it twice, once with quotes and once without?
There are two calls of the same method, with different arguments:
url = url.gsub "member_id", "member_id__hashed"
The arguments of url.gsub are the literal strings "member_id" and "member_id__hashed".
url = url.gsub member_id, member_id_hashed
This time the arguments are the variables member_id and member_id_hashed.
This works the same in JavaScript and many other languages that use double quotes to enclose the string literals.
String#gsub is a method of class String that does search & replace in a string and returns a new string. It's name is short of "global substitute" (it replaces all occurrences). To replace only the first occurrence use String#sub.

Resources