Name Value Lookup in Mule
Demonstration of the approaches to implement the name value lookup in Mulesoft and then conclude with the Mulesoft recommended approach, which is optimal.
Join the DZone community and get the full member experience.
Join For FreeI was recently working on API implementations for one of our clients using the MuleSoft cloud platform. One common thing that we needed to use across most of the APIs implementations is the name value lookup. There have been numerous blog posts and documentation showing various ways to implement the name value lookup functionality in Mule flows. In this blog, I will demonstrate the possible ways to implement lookup in Mule flows and then conclude the best and Mule-recommended approach to follow.
Approach 1: Name Value Lookup Using DataWeave Variables
In Mule DataWeave, we can keep the lookup data in HashMap format either on flow variables or inside DW, and then we can just use the keys to get the actual value. As shown in the below DataWeave code snippet, the variable “policybrand” has been used to keep the lookup data in HashMap format. The lookup has been done on the key "CommercialAuto," which returns the actual value "COMAUTO."
%dw 1.0
%output application/java
%var policybrand = {'CommercialAuto':'COMAUTO', 'CommercialProperty': 'COMPROP'}
---
{
policybrandvalue: policybrand['CommercialAuto']
}
Output of this will be policybrandvalue: COMAUTO.
We can also pass any element from payload or flowVars to make this key dynamic. As in the below DataWeave code snippet, we can see the brand element of the payload has been used as the key.
%dw 1.0
%output application/java
%var policybrand = {'CommercialAuto':'COMAUTO', 'CommercialProperty': 'COMPROP'}
---
{
policybrandvalue: policybrand[payload.brand]
}
Output of this will be policybrandvalue: <based on the value of payload.brand>.
This approach can be used when we have less lookup data with 100% visibility in the data set that we have to place in lookup HashMap. The major problem with this approach is it requires code changes whenever we have to add or modify any lookup data in the DataWeave. Also, when the lookup data doesn’t exist in the HashMap, the DataWeave transformation will fail with the exception.
Approach 2: Name Value Lookup Using the mule-app.properties File
To avoid code changes every time when we have to add/modify the lookup data, we can use a property file to store the lookup data and fetch it using a POM dependency from an external file. We can use the mule-app.properties file in this situation and fetch data from DataWeave using function p() or we can use the expression ${Key} to fetch the value in flowVars, which then can be used in DataWeave mapping.
Store lookup data in the mule-app.properties file like below:
policies.CommercialAuto=COMAUTO
policies.CommercialProperty=COMPROP
claims.CommercialAuto=COMAUTO
claims.CommercialProperty=COMPROP
Approach 2.1: Using DataWeave Function p()
Use the DataWeave function p() to fetch the lookup values using the key. In the below code snippet, we are fetching the value of key policies.CommercialAuto and claims.CommercialProperty.
%dw 1.0
%output application/java
---
{
policybrand: p('policies.CommercialAuto'),
claimsbrand: p('claims.CommercialProperty')
}
Output of this will bepolicybrand: COMAUTO claimsbrand: COMPROP
We can also pass any elements from payload or flowVars to make this key dynamic.
%dw 1.0
%output application/java
---
{
policybrand: p("policies."++paylod.policybrandcode),
claimsbrand: p("claims."++paylod.claimsbrandcode')
}
Output of this will be
policybrand: <based on the value of paylod.policybrandcode for example if
paylod.policybrandcode is"CommercialAuto" then value will be "COMAUTO"
>
claimsbrand: <
based on the value of paylod.policybrandcode
for example if
>paylod.claimsbrandcode is"CommercialAuto" then value will be "COMAUTO"
Approach 2.2: Using flowVar to Read Property Values
We can fetch the property value in the Mule flow variable using the expression ${Key} and then use the flowVars in Mule DataWeave to read the value. Please follow the below code:
<set-variable variableName="PoliciesLookupKey" value="${policies.CommercialAuto}" doc:name="Variable"/>
<set-variable variableName="ClaimsLookupKey" value="${claims.CommercialAuto}" doc:name="Variable"/>
%dw 1.0
%output application/java
---
{
policybrand: flowVars.PoliciesLookupKey,
claimsbrand: flowVars.ClaimsLookupKey
}
Output of this will bepolicybrand: COMAUTO claimsbrand: COMPROP
Lookup using the mule-app.properties file can be used to keep the lookup data outside the Mule configuration file. For every time we will make changes to the mule-app.properties data, we have to redeploy the Mule API to load the modified mule-app.properties file. Also, we have to make sure all the possible name value combinations are present in the mule-app.properties file, otherwise the lookup might fail with a DataWeave exception when the key is not found in the property file.
This approach will not be used when we need lookup data to be placed in multiple properties files for each line of business (policies lookup data in one file and claims lookup data in another file) as we can have only one mule-app.properties. This approach will also not be applicable if the values change between environments, as we can't have environment-based mule-app.properties files (this can be done using the POM file if we are using a Maven build for deployment). Also, mule-app.properties file is the mule default properties file for an API, and we don't have much control over it to define a specific property like "singleton," specify property file location,"ignoreUnresolvablePlaceholders," etc.
As we have seen, the above two approaches can be used to implement name value lookup in Mule flows, which looks standard but they are also not full proof in all the aspects, There are several other workaround which can also be used like writing custom java codes, creating flows/subflows specifically to write lookup etc.
Approach No 3. (Mule Recommended) Name Value Lookup using custom property file using context property placeholder.
The best possible solution which mule also recommend is to use custom lookup properties file using context. Place the custom propertis file in mule project under src/main/resources folder and load it using number of ways like expression language, using context-property notaiton or using spring beans notation. Please see the below code snippet for some examples.
<expression-language:property-placeholder location="lookup.properties" />
<spring:beans> <spring:bean id="appProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <spring:property name="singleton" value="true"/> <spring:property name="location" value="classpath:lookupFile.properties"/> </spring:bean> </spring:beans> <expression-language:property-placeholder location="lookup.properties" />
<context:property-placeholder location="lookup.properties"/>
We can also define multiple properties file to maintain seperate properties file for each line of business. Please see below code snippet for that expression.
<context:property-placeholder location="Policieslookup.properties","Claimslookup.properties"/>
The data can be placed in these custom properties file in same way as we have done in mule-app.properties file and can be accessed using DataWeave lookup function p() or using flow vars as described in the above Approach No 2.1 and Approach No 2.2. We can also use groovy expressions to use these prooerties file as mentioned below.
<set-variable value="#[groovy:appProps['policies.CommercialAuto']]" doc:name="PoliciesLookupCode" variableName="PoliciesLookupKey"/>
Opinions expressed by DZone contributors are their own.
Comments