How to read preauthorize expression from yaml file - spring

How to read #Preauthorize expression from property file?
I have expression in yaml file:
authorize:
exp: hasAnyAuthority('ROLE_XXX')
#PreAuthorize("${authorize.exp}")
public void blah(){
//something
}
SpelParseException is being thrown for above implementation.
Below is the stacktrace:
Caused by: org.springframework.expression.spel.SpelParseException: EL1041E:(pos 1): After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
at org.springframework.expression.spel.standard.InternalSpelExpressionParser.doParseExpression(InternalSpelExpressionParser.java:129)
I tried #PreAuthorize("#{authorize.exp}"), but same exception.
I don't want boolean to be read from property file, I want expression to be read.

Related

Compare Dates with Springboot Thymeleaf

I try to compare two dates with format yyyy-MM-ddTHH:mm:ss in a thymeleaf template.
I am able to compare a date, when I try:
${#dates.createNow().before(#dates.createNow())} // =false - just as an example
But my case is a bit tricky. At first I parse a string to obtain a date:
<th:block th:with="sdf = ${new java.text.SimpleDateFormat('yyyy-MM-dd''T''HH:mm:ss')}, isodate = ${isodate}, isodatemod = ${isodateModified}" >
Then I compare it:
<p th:switch="${#dates.format(sdf.parse(isodate)).before(#dates.format(sdf.parse(isodatemod)))}" />
This reveals the following error statement:
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "#dates.format(sdf.parse(isodatemod)).before(#dates.format(sdf.parse(isodatemod)))
[...]
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method before(java.lang.String) cannot be found on type java.lang.String
I just don't see, why after parsing my date, it is still seen as string? Is there any way to make these two dates comparable in thymeleaf?
I use the following import:
implementation group:"org.springframework.boot", name:"spring-boot-starter-thymeleaf"

How to access / address nested fields on Logstash

I am currently trying to convert a nested sub field that contains hexadecimal string to an int type field using Logstash filter
ruby{
code => 'event.set("[transactions][gasprice_int]", event.get("[transactions][gasPrice]").to_i(16))'
}
but it's returning the error
[ERROR][logstash.filters.ruby ][main][2342d24206691f4db46a60285e910d102a6310e78cf8af43c9a2f1a1d66f58a8] Ruby exception occurred: wrong number of arguments calling `to_i` (given 1, expected 0)
I also tried looping through json objects in transactions field using
transactions_num = event.get("[transactions]").size
transactions_num.times do |index|
event.set("[transactions][#{index}][gasprice_int]", event.get("[transactions][#{index}][gasPrice].to_i(16)"))
end
but this also returned an error of
[ERROR][logstash.filters.ruby ][main][99b05fdb6022cc15b0f97ba10cabb3e7c1a8fabb8e0c47d6660861badffdb28e] Ruby exception occurred: Invalid FieldReference: `[transactions][0][gasPrice].to_i(16)`
This method of conversion of hex-string to int type using a ruby filter worked when I wasn't dealing with nested fields, so can anyone please help me how to correctly address nested fields in this case?
btw,
this is the code that still works
ruby {
code => 'event.set("difficulty_int", event.get("difficulty").to_i(16))'
}
I think you have answered this one yourself in your final example - the to_i should not be inside the double quotes. So
...event.get("[transactions][#{index}][gasPrice].to_i(16)"))
should be
...event.get("[transactions][#{index}][gasPrice]").to_i(16))

How to get payload values from byte[] message in Spring Integration int-http:outbound-gateway?

I am configuring an outbound-gateway in my context.xml where I want to extract values from a byte[] type payload and use them to construct a URI. I found that SpEL allows you to build it this way:
url-expression="T(org.springframework.web.util.UriComponentsBuilder)
.fromHttpUrl('http://HOST:PORT/PATH')
.queryParams(payload)
.build()
.toUri()"
Source: https://docs.spring.io/spring-integration/reference/html/http.html#mapping-uri-variables
My variation of the solution looks like this:
<int-http:outbound-gateway id="candleRequestGateway"
request-channel="candleRequestChannel"
reply-channel="dataResponseChannel"
http-method="GET"
url-expression="T(org.springframework.web.util.UriComponentsBuilder)
.fromHttpUrl('some/{path}')
.queryParam('myParam', payload.get('myParam'))
.buildAndExpand(payload.get('path'))
.toUri()"/>
However, I am getting the following error which occurs while executing payload.get('myParam') part:
org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler#3]; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method get(java.lang.String) cannot be found on type byte[]
I understand and agree with the error. My question: is there a way (a specific SpEL expression(?)) to extract the values from byte[] payload without having to transform it before it reaches the outbound-gateway? Is this a valid solution at all?
Exactly what are you expecting payload.get('myParam') and payload.get('path') to do when the payload is a byte[].
Clearly, a byte[] does not have a get(String) method.
to extract the values from byte[]
Extract how? A byte[] is an unstructured array of bytes; the only thing you can do is something like new String(payload).substring(0, 5) or similar.
If the bytes contain JSON, you could use a #jsonPath SpEL function.

EL map lookup using string key containing single quote

I have a Java HashMap<String,String> that is being provided to a JSP page (itemTypesByKey) via a ModelAndView from Spring, and a separate structure containing a list of keys. (These keys may or may not result in a valid lookup.) I enumerate over these keys, and snag values from the map.
Map<String, String> itemTypes = new HashMap<>();
itemTypes.put("NormalValue", "INGREDIENT");
itemTypes.put("Apostro'Value", "INGREDIENT");
ModelAndView mav = ...
mav.addObject("itemTypesByKey", itemTypes);
The problem I'm seeing, is that if my key contains an apostrophe, the lookup fails.
My code (for debugging purposes):
Key Name: ${currentKeyName}
Not Empty: ${not empty itemTypesByKey[currentKeyName]}
Type: ${itemTypesByKey[currentKeyName]}
All Suite Types: ${itemTypesByKey}
Ends up printing, for two separate keys:
Key Name: NormalValue
Not Empty: true
Type: INGREDIENT
All Suite Types: {NormalValue=INGREDIENT, Apostro'Value=INGREDIENT}
Key Name: Apostro'Value
Not Empty: false
Type:
All Suite Types: {NormalValue=INGREDIENT, Apostro'Value=INGREDIENT}
I understand escaping apostrophe literals when they're used to lookup a value, but why does this fail if my key contains an apostrophe? How can I safely perform a lookup in my map regardless of whether the value of my key contains special characters?
Edit: I'm using Spring version 3.1.4 (mvc, expression, etc.), and this issue does not affect keys containing exclamation points, or other special characters I could think to test.
Below are some tests alongside results. In order to use an apostrophe inside of a key you have to use two single quotes. On top of that, a key that has a single quote in it or special characters (exclamation, double quotes, etc...) needs to have single quotes surrounding it. Bottom line is surround your keys with single quotes & use two single quotes if you have a single quote in your key.
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
Map<String,String> itemTypes = (Map) parser.parseExpression("{NormalValue:'INGREDIENT',ApostroValue:'INGREDIENT'}").getValue();
for (Map.Entry<String, String> e : itemTypes.entrySet())
System.out.println(e.getKey() + ": " + e.getValue());
}
Prints keys & values fine
parseExpression("{NormalValue:'INGREDIENT',Apostro'Value:'INGREDIENT'}")
Exception in thread "main" org.springframework.expression.spel.SpelParseException: EL1046E:(pos 51): Cannot find terminating for string
parseExpression("{NormalValue:'INGREDIENT',Apostro''Value:'INGREDIENT'}")
Exception in thread "main" org.springframework.expression.spel.SpelParseException: EL1043E:(pos 33): Unexpected token. Expected 'colon(:)' but was 'literal_string'
parseExpression("{NormalValue:'INGREDIENT','Apostro''Value':'INGREDIENT'}")
Prints fine
parseExpression("{NormalValue:'INGREDIENT',Apostro\"Value:'INGREDIENT'}")
Exception in thread "main" org.springframework.expression.spel.SpelParseException: EL1045E:(pos 33): Cannot find terminating " for string
parseExpression("{NormalValue:'INGREDIENT','Apostro\"Value':'INGREDIENT'}")
Prints fine
parseExpression("{NormalValue:'INGREDIENT',Apostro!Value:'INGREDIENT'}")
Exception in thread "main" org.springframework.expression.spel.SpelParseException: EL1043E:(pos 33): Unexpected token. Expected 'colon(:)' but was 'not(!)'
parseExpression("{NormalValue:'INGREDIENT','Apostro!Value':'INGREDIENT'}")
Prints fine

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

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.

Resources