【问题标题】:Mule 3.9.0 CE payload problem with transformationMule 3.9.0 CE 有效载荷问题与转换
【发布时间】:2021-02-18 17:53:59
【问题描述】:

我正在写一个我在 MULE CE 3.9.0 运行时中注意到的非常奇怪的问题。我什至认为,这是整个事情中的一个错误。 重点: 有一个使用 Mule 3.9.0 构建的 API Manager。 然后通过邮递员发出一些请求后,API GW 正在捕获它,第一件事是将原始有效负载保存到某个变量。假设stored_payload

然后我进行一些 ASYNC 调用来记录这个请求(对另一个微服务的 REST 请求)。里面全是message_enricher。

在这个异步调用中,我需要记下有效负载(在 var:stored_payload 中)。显然是Buffer Input Stream,所以我首先需要将其转换为字符串。 我们知道有效载荷是可变的,所以我不能使用 Mule 转换器,但需要在 Grovvy 中编写自己的。

IOUtils.toString({stored_payload}, 'UTF-8')

可以做到。

之后,我会返回调用真正的业务 API,这就是我的问题。 似乎在stored_payload 上进行Grovvy 操作时,没有设置和发送的BODY 来调用真正的业务API。 (payload 为空,但原始stored_pa​​yload 仍为BufferInputStream)。

我正在附加所需的 XML:

<flow name="logInputRequest">
    <set-variable variableName="params" value="#[new java.util.HashMap();]" doc:name="define FlowVars MAP"/>

 <scripting:component doc:name="Create request params">
                                                <scripting:script engine="Groovy"><![CDATA[import org.json.JSONArray;
    import org.json.JSONObject;
    import java.lang.String;
    import org.apache.commons.io.IOUtils;
    import java.io.StringReader;
    import java.nio.charset.StandardCharsets;
    
def transformedPayload = IOUtils.toString(message.getInvocationProperty('stored_payload'), 'UTF-8')
if(message.getInvocationProperty('as_context') != null){
        JSONObject obj = new JSONObject(message.getInvocationProperty('as_context'));
        if(obj != null && obj.getJSONObject("accessTokenInfo") != null){
            JSONObject accessTokenInfo = obj.getJSONObject("accessTokenInfo");
            flowVars.params.put("ownerCif",obj.getString("cif"));
            flowVars.params.put("userNik", accessTokenInfo.getInt("user"));
            flowVars.params.put("ownerNik", obj.getString("owner"));
            flowVars.params.put("userCif", accessTokenInfo.getInt("userId"));
        }
    }
flowVars.params.put("isResponse",false);
flowVars.params.put("parentSpanId", message.getInvocationProperty("x-b3-parentspanid"));
    flowVars.params.put("httpStatus", null);
    flowVars.params.put("description", "Request invoked successfully");
    flowVars.params.put("hostName", message.getInvocationProperty('remote_address') + ' (Mule)');
 
flowVars.params.put("apiUri", flowVars.endpoint);
flowVars.params.put("payload", "URI: "+ message.getInvocationProperty('incoming_properties')['http.request.uri'] + 
    " PARAMS: " + message.getInvocationProperty('query_params').toString() + 
    " PAYLOAD: "+ transformedPayload);
    flowVars.params.put("correlationId", message.getInvocationProperty('requestId'));

<flow-ref name="logCreateParamshttpRequest" doc:name="Log Platform Create REF"/>

</flow>

还有 flow-ref DEF:

<flow name="logCreateParamshttpRequest">
<flow-ref name="encodeHmacAndAddToSession" doc:name="encodeHmac"/>
<set-payload value="#[flowVars.params]" encoding="UTF-8" mimeType="application/json" doc:name="Set Body"/>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<http:request config-ref="openapi-admin" path="/platform/log/create" method="POST" doc:name="Log Platform Create">
<http:request-builder>
                    <http:header headerName="Authorization" value="Bearer #[flowVars.keycloak]"/>
                    <http:header headerName="Hmac" value="#[sessionVars.hmac]"/>
                </http:request-builder>
            </http:request>
            <catch-exception-strategy doc:name="Catch Exception Strategy">
                <logger message="################# ERROR - While creating request for Admin Log. Process will continue as it's not necessary to be valid in whole flow. Error message: #[flowVars.errorMessage or org.apache.commons.lang3.StringEscapeUtils.escapeJson(exception.?getCauseException().?getMessage())]" level="INFO" doc:name="Logger"/>
            </catch-exception-strategy>
</flow>

第一个流程(开始一切)是异步的。

[....... some beggining code.....]
<logger message="BEFORE 1 REQUEST #[flowVars.stored_payload] #[payload]" level="INFO" doc:name="Logger"/>
<async doc:name="Async">
<enricher target="#[flowVars.logInput]" doc:name="Log input request">
<flow-ref name="logInputRequest" doc:name="LOG INPUT REQUEST"/>
</enricher> 
</async>
<logger message="AFTER 1 REQUEST #[flowVars.stored_payload] #[payload]" level="INFO" doc:name="Logger"/>

是否有任何机会,上述变量的设置会改变整个有效负载,这就是为什么它没有发送到真正的商业 API? 任何帮助将不胜感激。

【问题讨论】:

  • 如何在异步中写入字符串?请分享异步的 XML 及其内容。
  • 另外,你把 Groovy 放在哪里了,在 Async 内部还是之前?在流程的其余部分中使用的有效负载是什么?
  • @aled 我确实共享了 XML。 Groovy 在 Async 内部。 Payload是一个json,但是当它开始执行时,它显然是BufferInputStream。

标签: mule transformation


【解决方案1】:

如果没有更多详细信息,则无法确定,但最可能的原因是该流被流的其余部分中的不同线程消耗。如果负载是对流的引用,如果它被另一个线程完全读取(异步作用域在它自己的线程中运行),那么对它的任何引用都会发现它是空的。

作为替代方案,如果您在异步之前将流转换为字符串,它将在异步范围内外可用,但如果它太大,可能会导致内存问题,因为字符串必须完全存在于内存中,这与流不同.

【讨论】:

  • 我虽然这么说你做了,但是当我不将“stored_pa​​yload”转换为字符串时,这是正常的,没关系。正文已发送。唯一的区别是:如果没问题,我不转换有效负载(但我需要),有错误的情况:我按照我写的那样做。
  • 如果它在不转换为 String 时有效,为什么需要这样做? HTTP 请求者,可能还有大多数 Mule 操作,理解流并且不需要转换。
  • 是的,这是真的,但我的流程的一个业务案例是将有效负载作为纯文本发送并从数据库中读取。当我不从 Stream 转换它时,我会得到像“BufferInputStream@435sda”这样的东西,这是不可接受的。
  • 看起来您需要在异步之前对流进行序列化(在这种情况下转换为字符串)。您之前是否尝试过仅将对象添加到字符串转换器?
  • 对不起,我在异步之前没说。
猜你喜欢
  • 2023-01-05
  • 1970-01-01
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多