How can i assign Mule Variable Value to Property Key -Value lookup? - groovy

I want to find out the careerName from variable
I want to use that CareerName as Property Key. Example. If careerName came-up as apple, I have value setup against that key apple=ST\*214|ST\*210.
I have following line of code for Mule Choice Expression, which i tried with but i am not getting success here.
mule-esb.test1.properties
ftp.inbound.carriers.path='CareerName1/InBound/','CareerName2/InBound/','CareerName3/InBound','CareerName4/InBound/','apple/InBound/'
CareerName1=ST\*214|ST\*210
CareerName2=ST\*214|ST\*210
CareerName3=.\ST.214.\
CareerName4=ST\*214
apple=ST\*214
<context:property-placeholder location="mule-esb.${mule.env}.properties" />
<when expression="import java.util.regex.Pattern;Pattern p = Pattern.compile('${'+message.getInvocationProperty('careerName')+'}');return p.matcher(payload.toString()).find();" evaluator="groovy">
Looking for some alternatives or solution on this script.

MEL has extensive regex support, you shouldn't need to use Groovy. See: http://www.mulesoft.org/documentation/display/current/Mule+Expression+Language+Tips#MuleExpressionLanguageTips-RegexSupport
You need to load your properties in an Map that you can query from the registry but also use in the property placeholder resolver. So do this:
<util:properties id="configProperties"
location="classpath:mule-esb.${mule.env}.properties" />
<context:property-placeholder properties-ref="configProperties" />
With this in place, the following should work:
<when expression="#[regex(app.registry.configProperties[careerName])]">

define a spring bean globally configuring the key value pair properties for the bean.
the bean definition should accept the spring properties and a method which accept the key and returns the corresponding value.
sample bean definition as follows
<spring:bean id="entityMapper" name="entityMapper" class="com.xx.xx.commons.ClassNameXX">
<spring:property name="entities">
<spring:props>
<spring:prop key="CareerName1">${CareerName1}</spring:prop>
.
.
</spring:props>
</spring:property>
</spring:bean>
so in the flow level you can get value from bean with below expression.
#[app.registry.entityMapper.getEntity(message.getInvocationProperty('careerName'))]
where entityMapper will be the bean name and getEntity is the method defined in bean which accept the careerName and return the corresponding value.
hope this helps.
Dynamically you cant access the value directly from context placeholder.

Related

Mule 3 retrieving the placeholder value dynamically

I have a use-case that I need to retrieve the value from my properties file but that key should be derived dynamically from my query params.
How to handle this in MEL or Groovy? I am aware it is possible in DW.
Http request
https://localhost:9898/getStore?search=customer.weststore.name
And my placeholders are -
file.properties
customer.weststore.name=TESTING
customer.eaststore.name=IRERRER
So the way I need to access something like this
<set-variable variableName="westDetail" value="#[message.inboundProperites['customer.weststore.name']" doc:name="Variable"/>
<logger message="${westDetail}" level="INFO" /> --> Failed as no placeholder available
When I tried the above it's failing due to no placeholder as "westDetail" available whereas I need the fetch that particular key from the properties file.
This is something related to this article - https://help.mulesoft.com/s/question/0D52T00004mXTQUSA4/dynamically-read-property-values-from-a-properties-file-in-mule but the only solution provided with DW not MEL or Groovy.
How anyone advises, Is it possible?
I understand that the problem is that you want to query the properties by a key that is obtained at execution.
You are doing it incorrectly. ${} is for evaluating the value of a property, which is done at initialization time of the application. You missed that get the actual value in the set-variable.
#[] is for executing a MEL expression, which happens at execution time. flowVars.westDetail is a MEL expression that returns the value of flow variable westDetail. You can't use a MEL expression to evaluate the property placeholder ${}, because they are evaluated at different times.
A solution is to use a Spring bean to store the properties, instead of a configuration properties placeholder. Then you can assign it to a flow variable and access it like a map.
Example:
<spring:beans>
<spring:bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<spring:property name="location" value="classpath:items.properties"/>
</spring:bean>
</spring:beans>
<flow name="myFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<set-variable value="#[app.registry.myProperties]" variableName="props"></set-variable>
<logger message="a=#[flowVars.props['a']]" level="INFO"/>
</flow>
items.properties:
a=1
b=2
c=3
Output:
a=1

How to set payload as constructor-arg value in service-activator

I've started with SI and kind of stuck right now as we want to use SI in one of our existing project avoiding changes where we can.
A bean which we would be using as a service activator accepts an constructor argument of a java object.
that object is in the payload but then I'm unable to set it using inner bean usage of service-activator
<service-activator input-channel="ADMIN_TEST_CONNECTION" method="testConnection">
<beans:bean class="mypackage.request.AdminRequestProcessor">
<beans:constructor-arg value="payload"/>
</beans:bean>
</service-activator>
it's complaining about Could not convert argument value of type [java.lang.String] to required type.
Please help in how to access payload and set it as an constructor argument.
If I go via non- constructor arg route and change existing java object then it works with this call in the service activator
expression="#bean.testConnection(payload)"/>
but I don't wish you to change the existing java code until there is no other way.
I think you don't have choice unless change something or add code around existing.
Service-Activator performs its functionality against each incoming message in the input-channel. And that functionality is exactly method invocation where Message is used as a context for method arguments.
Not sure what you are going to do with that payload, but that doesn't look correct to use statefull object like your AdminRequestProcessor. Just don't forget that you may have many incoming message, but service-activator should be consistent.
Plus don't forget that <beans:bean> is singleton, so your AdminRequestProcessor is instantiated only once.
Looking to your sample I'd suggest something like this:
expression="new AdminRequestProcessor(payload).testConnection()"/>
If you really don't want to change anything in your code.
Everything rest you can find in the Reference Manual.

Spring Integration jdbc stored procedure custom rowmapper

I am newbie to Spring Integration and am using Spring 4.2.4.
I am trying to invoke stored procedure with jdbc:stored-proc-outbound-gateway. i am already using spring jdbc.
Stored procedure is returning cursor and am using customRowMapper like below
new SqlOutParameter(A_RC, OracleTypes.CURSOR, null, new MyCustomDataExtractor())
MyCustomDataExtractor implements SqlReturnType and it returns custom object.
Now the question is how can I achieve this in SI jdbc stored proc.piece of my code here..
...
<int-jdbc:sql-parameter-definition name="A_RC" type="#{T(oracle.jdbc.OracleTypes).CURSOR}" direction="OUT"/>
...
<int-jdbc:returning-resultset name="A_RC" row-mapper="a.b.c.MyCustomDataExtractor"/>
...
Spring expect this as a row mapper. should I use any transformer here? Please advice.
Note : I have to return multiple resultset.
Actually with the CURSOR type you are good to go with just a returning-resultset and RowMapper implementation.
With that you don't need to worry about any SqlReturnType and just map the row to your domain object directly.
I'm even sure you can rework your MyCustomDataExtractor to the RowMapper contract.
Note: with returning-resultset defintion you don't need to
specify the sql-parameter-definition for the same OUT param. The component identifies them correctly as a OutParameter.
And, yes you can have several returning-resultset for CURSOR parameters.
I added the return-type in the sql-parameter-definition and removed returning-resultset.
<int-jdbc:sql-parameter-definition name="A_RC" type="#{T(oracle.jdbc.OracleTypes).CURSOR}" direction="OUT" return-type="ed"/>
and here "ed" is nothing but the bean reference for a.b.c.MyCustomDataExtractor.
<bean id="ed" class="a.b.c.MyCustomDataExtractor"/>

Access value from a Map where Key is Enum Type in JSF Facelets

I have a Map defined in my controller as follows
Map<AddressTypeEnum,Address> addressMap = new HasMap<AddressTypeEnum,Address>();
where AddressTypeEnum is a Enum type with values as HOME,WORK
in facelets, I was trying to access the field of Address as follows
<p:inputText value="#{controller.addressMap['HOME'].addressLine1}"/>
It gives me error target not reachable as null. Is there any thing wrong with my facelets code
Thanks in advance
I have resolved the issue as follows.. May be useful to others
I used Ominifaces from BaluC
In the facelets page, I added the follwing line
<o:importConstants type="com.eplm.chits.entities.common.AddressTypeEnum" var="addressType"/>
Then I used
<p:inputText id="homeId" value="#{chitUserController.address[addressType.HOME].addressLine1}"/>
EL doesn't have built-in functionality to work with Enums. You can only test if Enum-typed variable holds some value like in: rendered="#{enumVar=='HOME'}", because in this case implicit call to enumVar.toString() is executed.
Probably, using Enum as the key for your Map, you want to enforce compile-time checking of your keys. You could use Map<String, Address> and addressMap.put(AddressTypeEnum.HOME.toString(), someAddress) instead.
From facelets template you then access addressMap either with
#{controller.addressMap['HOME'].addressLine1}
or with
#{controller.addressMap.HOME.addressLine1}.
Another solution would be to introduce controller method, as #sleske advises, which takes String parameter, gets Enum instance for this String and gets the value from the map:
Map<AddressTypeEnum, Address> addressMap;
...
public Address getAddress(String type) {
AddressTypeEnum addressType = AddressTypeEnum.valueOf(type);
return addressMap.get(addressType);
}
...and use it with #{controller.getAddress('HOME').addressLine1}
UPD: There is three-years-old StackOverflow question on the same problem: Passing a Enum value as a parameter from JSF (revisited)
If you're using Primefaces, it is possible to use the <p:importEnum /> tag, as described in: Primefaces's showcase:
<p:importEnum type="javax.faces.application.ProjectStage"
var="JsfProjectStages"
allSuffix="ALL_ENUM_VALUES"/>
<h:outputText value="#{JsfPRojectStages.Key}" />

SpringSecurity: ifAnyGranted roles as property

how is it possible to pass the allowed roles as property?:
<sec:ifAnyGranted roles="#{item.allowedRolesToRender}">
Where Item is not a bean but the var of an dataList:
<rich:dataList value="${handler.itemlist}" var="item"
I tried to return array/comma-separated-string/list but it seems the the get method is never called. And i always get:
com.sun.facelets.FaceletException: roles must be given
at org.springframework.security.taglibs.facelets.IfAnyGrantedTag.apply(IfAnyGrantedTag.java:41)
Thanks
Use like this.
<sec:authorize ifAnyGranted="#{item.allowedRolesToRender}">
And allowedRolesToRender should be given as a comma-separated list of strings
Reference

Resources