简体   繁体   English

如何控制Mule Cache中的密钥生成

[英]How to control key generation in Mule Cache

My requirement is to authenticate the user (with an external ws) as part of my Mule Flow and use the result of the authentication in a cache. 我的要求是将用户(使用外部ws)作为我的Mule Flow的一部分进行身份验证,并在缓存中使用身份验证的结果。 however, if the user credentials change, then the cache should be automatically invalidated and user auth must be done with the external ws. 但是,如果用户凭据发生更改,则应自动使缓存失效,并且必须使用外部ws完成用户身份验证。 Basically the cache key should be based on the user credentials. 基本上,缓存键应基于用户凭据。 Is this possible ? 这可能吗 ?

Here's my mule flow and i see that Mule is caching the results after the first request and irrespective of whether or not the payload changes in subsequent requests ( which is where the credentials are sent ) mule always returns the results from the cache. 这是我的骡子流,我看到Mule在第一次请求后缓存结果,无论有效负载是否在后续请求中发生变化(这是发送凭证的位置),mule总是返回缓存中的结果。 So when the first request has incorrect credentials, user auth fails and mule caches the response. 因此,当第一个请求具有不正确的凭据时,用户身份验证失败并且mule缓存响应。 From this point onwards, irrespective of sending correct credentials in subsequent requests, it always refers to the cache and returns user auth failure. 从此时起,无论在后续请求中发送正确的凭据,它始终引用缓存并返回用户身份验证失败。 How do I achieve what I wanted to achieve ? 我如何实现我想要实现的目标?

Here's my mule flow: 这是我的骡子流:

    <?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>

Since the default key generation strategy for the cache scope is based on the message payload an option in your particular case would be to simply move the scripting:transformer to be executed before the ee:cache scope. 由于缓存作用域的默认密钥生成策略基于消息有效内容,因此在您的特定情况下,只需移动scripting:transformer即可在ee:cache作用域之前执行。

For a more general solution, where you do not want to overwrite your request payload, you can define the keyGenerationExpression or keyGenerator-ref attribute on the ee:cache element to control how the cache key i generated. 对于更通用的解决方案,您不希望覆盖请求有效负载,可以在ee:cache元素上定义keyGenerationExpressionkeyGenerator-ref属性,以控制生成的缓存键的方式。

For example to use the complete HTTP authorization header as key you could use: 例如,要使用完整的HTTP授权标头作为密钥,您可以使用:

 <ee:cache cachingStrategy-ref="Auth-Cache-Strategy" doc:name="Cache"
      keyGenerationExpression="#[message.inboundProperties.authorization]">
     <!-- Your flow here --> 
 </ee:cache>

See the cache scope documentation for more information. 有关更多信息,请参阅缓存范围文档

If you want to use this approach you could do is move parts of your jython code outside the cache scope, change it so that it sets the user and password as separate flow variables on the message and then use them in the keyGenerationExpression and then again later inside the cache scope in a simple set-payload transformer. 如果你想使用这种方法,你可以做的是将jython代码的一部分移到缓存范围之外,更改它以便将用户和密码设置为消息上的单独流变量,然后在keyGenerationExpression使用它们,然后再次使用它们在简单的set-payload转换器中的缓存范围内。

You can define a global configuration "Caching_Strategy" : 您可以定义全局配置“Caching_Strategy”

<ee:object-store-caching-strategy name="Caching_Strategy" keyGenerationExpression="#[flowVars.userID]" doc:name="Caching Strategy"/>

and refer the global configuration in cache flow: 并在缓存流程中引用全局配置:

<ee:cache doc:name="Cache" cachingStrategy-ref="Caching_Strategy">
<!-- flow -->
</ee:cache>

You can control your keyGenerationExpression by the flow variable #[flowVars.userID] 您可以通过流变量#[flowVars.userID]控制keyGenerationExpression

For complete detail with example refer http://www.tutorialsatoz.com/caching-in-mule-cache-scope/ 有关示例的完整详细信息,请参阅http://www.tutorialsatoz.com/caching-in-mule-cache-scope/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM