Search code examples
cachingmulemule-componentmule-esb

How to Cache DB Query Result and avoid cache from processing the mule message irrespective of incoming request?


I am caching third-party API URL from DB and this URL must be used by subsequent incoming messages to hit third-party system.

Currently whenever i do any change in the incoming request then the URL is again loaded from DB and when is send same request again and again then the URL is fetched from cache.

But i want the URL to be loaded for first time and then should be fetched from cache irrespective of the content in incoming request.

please let me know how to do it?

MULE XML:

<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081" doc:name="HTTP Listener Configuration"/>
<http:request-config name="HTTP_Request_Configuration" host="lcdre342.cdr-p01.chp.bankofamerica.com" port="20108" basePath="/ngen/AdministerAccountRelationshipManagement/V001/administer-accounts" doc:name="HTTP Request Configuration"/>
<http:request-config name="HTTP_Outgoing_Request" host="#[sessionVars.api_url]" port="${mule.env.port}" doc:name="HTTP Request Configuration"/>
<context:property-placeholder location="${mule.env}.properties"/>
<db:generic-config name="Generic_Database_Configuration" url="jdbc:db2://db2dvipa9sd92t.bankofamerica.com:446/D92T:user=${mule.env.dbuserName};password=${mule.env.dbPassword};" driverClassName="com.ibm.db2.jcc.DB2Driver" doc:name="Generic Database Configuration"/>
<ee:object-store-caching-strategy name="API_Url_cache" doc:name="Caching Strategy">
    <managed-store storeName="API URL Managed Store" persistent="true" maxEntries="1" entryTTL="600000" expirationInterval="6000"/>
</ee:object-store-caching-strategy>
<flow name="ringfencedemoFlow">
    <http:listener config-ref="HTTP_Listener_Configuration" path="/administer-accounts" allowedMethods="POST" doc:name="HTTP">
        <http:response-builder statusCode="#[message.inboundProperties.'http.status']" reasonPhrase="#[message.inboundProperties.'http.reason']">
            <http:header headerName="x-boa-site-affinity" value="#[message.inboundProperties.'x-boa-site-affinity']"/>
            <http:header headerName="x-boa-site-affinity-wcc" value="#[message.inboundProperties.'x-boa-site-affinity-wcc']"/>
            <http:header headerName="x-boa-trace-id" value="#[message.inboundProperties.'x-boa-trace-id']"/>
        </http:response-builder>
    </http:listener>
    <object-to-string-transformer doc:name="Object to String"/>
    <logger message="#[payload]" level="INFO" doc:name="Input Request Logger"/>
    <set-variable variableName="inputMsg" value="#[payload]" doc:name="Put input request into variable"/>
    <ee:cache doc:name="Cache" cachingStrategy-ref="API_Url_cache" filterExpression="#[payload.isEmpty() == false]">
        <db:select config-ref="Generic_Database_Configuration" doc:name="Get API url from DB">
            <db:parameterized-query><![CDATA[select data_value from ${mule.env.schemavalue}.XWCCSYSPARM where GROUPREFID='WCCD' and CATEGORY='MULE' and KEY_ID='WCC_API_URL' and SEQ_NUM=0]]></db:parameterized-query>
        </db:select>
    </ee:cache>
    <set-session-variable variableName="api_url" value="#[payload.get(0).DATA_VALUE]" encoding="UTF-8" mimeType="text/plain" doc:name="Set Api url in session variable"/>
    <set-payload value="#[flowVars.inputMsg]" encoding="UTF-8" mimeType="application/xml" doc:name="Set back input request in payload"/>
    <http:request config-ref="HTTP_Outgoing_Request" path="${mule.env.path}" method="POST" doc:name="Call to WCC System">
        <http:request-builder>
            <http:header headerName="x-boa-user-id" value="#[message.inboundProperties.'x-boa-user-id']"/>
            <http:header headerName="X-BOA-Trace-ID" value="#[message.inboundProperties.'X-BOA-Trace-ID']"/>
            <http:header headerName="X-BOA-RDS-Auth-ChannelId" value="#[message.inboundProperties.'X-BOA-RDS-Auth-ChannelId']"/>
            <http:header headerName="X-BOA-RDS-Auth-AppId" value="#[message.inboundProperties.'X-BOA-RDS-Auth-AppId']"/>
            <http:header headerName="X-BOA-Security-Token" value="#[message.inboundProperties.'X-BOA-Security-Token']"/>
            <http:header headerName="X-BOA-User-ID-Type" value="#[message.inboundProperties.'X-BOA-User-ID-Type']"/>
            <http:header headerName="X-BOA-Originator-Component" value="#[message.inboundProperties.'X-BOA-Originator-Component']"/>
        </http:request-builder>
        <http:success-status-code-validator values="200,400,207"/>
    </http:request>
    <object-to-string-transformer doc:name="Object to String"/>
   <!--  <component doc:name="PrettyPrintXML" class="org.boa.format.PrettyPrintXML"/> -->
    <logger message="#[payload]" level="INFO" doc:name="Response logger"/>
</flow>

Solution

  • You need to set the keyGenerationExpression attribute on your caching-strategy, like this:

    <ee:object-store-caching-strategy name="API_Url_cache" doc:name="Caching Strategy"
    keyGenerationExpression="#[flowVars.someConstantVariable]">
       <managed-store storeName="API URL Managed Store" persistent="true" maxEntries="1" entryTTL="600000" expirationInterval="6000"/>
    </ee:object-store-caching-strategy>
    

    The cache entries are stored in cache based on the key generated. The next time cache scope is executed, the newly generated key is matched with the stored key(s) to decide if it's a CACHE HIT or CACHE MISS.

    In your case, the key generated by Mule's default key generator is probably unique for each message request. Therefore the cache scope is executed each time.

    From https://docs.mulesoft.com/mule-user-guide/v/3.8/cache-scope - enter image description here

    Few examples for a constant key generation:

    // Generates same key whenever payload is not empty
    keyGenerationExpression="#[!payload.isEmpty()]" 
    
    // Generates same key for a calendar month
    keyGenerationExpression="#[server.dateTime.month]" 
    

    HTH.