Caching 如何控制Mule缓存中的密钥生成

Caching 如何控制Mule缓存中的密钥生成,caching,mule,Caching,Mule,我的需求是使用外部ws作为Mule流的一部分对用户进行身份验证,并在缓存中使用身份验证的结果。但是,如果用户凭据发生更改,则缓存应自动失效,并且必须使用外部ws完成用户身份验证。基本上,缓存密钥应该基于用户凭据。这可能吗 这是我的mule流,我看到mule在第一个请求之后缓存结果,而不管负载是否在后续请求中发生变化(凭证发送的位置),mule总是从缓存返回结果。因此,当第一个请求的凭据不正确时,用户身份验证失败,mule缓存响应。从这一点开始,无论在后续请求中发送正确的凭据,它都会引用缓存并返回

我的需求是使用外部ws作为Mule流的一部分对用户进行身份验证,并在缓存中使用身份验证的结果。但是,如果用户凭据发生更改,则缓存应自动失效,并且必须使用外部ws完成用户身份验证。基本上,缓存密钥应该基于用户凭据。这可能吗

这是我的mule流,我看到mule在第一个请求之后缓存结果,而不管负载是否在后续请求中发生变化(凭证发送的位置),mule总是从缓存返回结果。因此,当第一个请求的凭据不正确时,用户身份验证失败,mule缓存响应。从这一点开始,无论在后续请求中发送正确的凭据,它都会引用缓存并返回用户身份验证失败。我如何实现我想要实现的目标

这是我的骡子流程:

    <?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.6.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd">
    <http:listener-config name="HTTP-Inbound-Endpoint" host="0.0.0.0" port="8888" doc:name="HTTP Listener Configuration"/>
    <http:request-config name="HTTP_Request_Configuration" host="10.10.10.10" port="8080" doc:name="HTTP Request Configuration"/>
    <ee:object-store-caching-strategy name="Auth-Cache-Strategy" doc:name="Caching Strategy">
        <in-memory-store name="UserAuthCache" maxEntries="100" entryTTL="3600" expirationInterval="3600"/>
    </ee:object-store-caching-strategy>
    <flow name="cacheauthenticationFlow">
        <http:listener config-ref="HTTP-Inbound-Endpoint" path="*" doc:name="HTTP"/>
        <object-to-string-transformer doc:name="Object to String"/>
        <ee:cache cachingStrategy-ref="Auth-Cache-Strategy" doc:name="Cache">
            <logger message="Incoming: #[message.payload]" level="INFO" doc:name="Logger"/>
            <scripting:transformer doc:name="Python">
                <scripting:script engine="jython"><![CDATA[import base64
authorization = message.getInboundProperty("authorization")
#print "Authorization is: \"" + authorization + "\""
authstring = authorization.split()
#print authstring
credentials = authstring[-1]
#print "Credentials => " + credentials

decodedAuth = credentials.decode('base64')
#print decodedAuth
if (decodedAuth.find("@") > 0):
    (id, password) = decodedAuth.split(":")
    (username, project) = id.split("@")
    print username + ":" + password + ", Project: " + project
else:
    (username, password) = decodedAuth.split(":")
    print username + ":" + password

message.payload = { "username" : username + "@" + project , "password" : password }
result = message]]></scripting:script>
            </scripting:transformer>
            <json:object-to-json-transformer doc:name="Object to JSON"/>
            <logger message="Incoming payload: #[message.payload]" level="INFO" doc:name="Logger"/>
            <http:request config-ref="HTTP_Request_Configuration" path="/wservices/authenticate/user" method="POST" doc:name="HTTP-Dev-Box-Authentication"/>
            <object-to-string-transformer doc:name="Object to String"/>
        </ee:cache>
        <logger message="Response From Cache: #[message.payload]" level="INFO" doc:name="Logger"/>
        <set-payload value="#[message.payload.'status']" doc:name="Response"/>
    </flow>
</mule>

由于缓存作用域的默认密钥生成策略是基于消息有效负载的,因此在特定情况下,您可以选择将要执行的scripting:transformer移动到ee:cache作用域之前

对于更通用的解决方案,如果不想覆盖请求负载,可以在ee:cache元素上定义keyGenerationExpression或keyGenerator重构属性,以控制如何生成缓存键

例如,要使用完整的HTTP授权标头作为密钥,可以使用:

 <ee:cache cachingStrategy-ref="Auth-Cache-Strategy" doc:name="Cache"
      keyGenerationExpression="#[message.inboundProperties.authorization]">
     <!-- Your flow here --> 
 </ee:cache>
有关更多信息,请参阅


如果要使用这种方法,可以将jython代码的一部分移到缓存范围之外,更改它,使其将用户和密码设置为消息上的单独流变量,然后在keyGenerationExpression中使用它们,然后在简单的set payload transformer中的缓存范围内再次使用它们。

您可以定义全局配置缓存策略:

并参考缓存流中的全局配置:

<ee:cache doc:name="Cache" cachingStrategy-ref="Caching_Strategy">
<!-- flow -->
</ee:cache>
您可以通过流变量[flowVars.userID]控制keyGenerationExpression

有关示例的完整详细信息,请参阅

谢谢我们。我使用了keyGenerationExpression,它现在可以工作了。但是,我有一个缓存到期的问题。我已配置内存存储。不管我在TTL中配置了什么,缓存总是每3-4个请求命中一次原始ws。如果我没有设置TTL或到期时间间隔,那么除非我的密钥改变,否则它永远不会到达原始ws。将缓存过期时间配置为5分钟的正确方法是什么。5分钟后,我的缓存必须失效,后续请求必须引用原始ws,并将结果缓存5分钟,以此类推。
<ee:cache doc:name="Cache" cachingStrategy-ref="Caching_Strategy">
<!-- flow -->
</ee:cache>