Mule 4.1.4通过HTTP POST请求上传压缩的xml文件内容失败

问题描述 投票:0回答:2

我正在将Mule 3.9文件上传逻辑迁移到Mule 4.1.4版本。为简单起见,在Mule 4.1.4中我尝试使用基本逻辑使用http连接器上传压缩的xml文件内容以发布到HTTP POST请求,它继续使用BAD_REQUEST失败,没有得到我输入的错误。请建议我在里面缺少什么?

Mule 3.9现有工作代码:

<flow name="Post_XML_To_ExtSystem" processingStrategy="synchronous">
        <timer-interceptor/>
        <object-to-byte-array-transformer doc:name="Object to Byte Array"/>
        <gzip-compress-transformer doc:name="Gzip Compress"/>
        <logger message="gZip compression completed for Part: #[flowVars.partId]" level="INFO" doc:name="gZip completed"/>
        <flow-ref name="WriteToFile_Flow" doc:name="Write to File Optionally"/>
        <set-variable variableName="fileContentgzip" value="#[payload]" doc:name="fileContentgzip"/>
        <flow-ref name="SetAttachments_PostPayload_Flow" doc:name="SetAttachments_PostPayload_Flow - FlowRef"/>
        <exception-strategy ref="Global_Errorflow_Choice_Exception_Strategy" doc:name="Reference Exception Strategy"/>
</flow>

<sub-flow name="SetAttachments_PostPayload_Flow">
        <logger message="Post Payload Flow with vars: #[flowVars]" level="DEBUG" doc:name="Logger"/>
        <set-attachment attachmentName="TenantID" value="#['${http.ext.system.tenant}']" contentType="text/plain" doc:name="Tenant ID"/>
        <set-attachment attachmentName="Category" value="#[flowVars.Category]" contentType="text/plain" doc:name="Category"/>
        <set-attachment attachmentName="Data" value="#[flowVars.fileContentgzip]" contentType="application/xml" doc:name="Data"/>
        <scripting:component doc:name="filename attachment">
            <scripting:script engine="Groovy"><![CDATA[import org.mule.message.ds.ByteArrayDataSource;
import javax.activation.DataHandler;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

String category = message.getInvocationProperty("Category")
String fileName=category + '.xml'
String attachmentName='Data'

byte[] compressed = flowVars.fileContentgzip
ByteArrayDataSource attachment = new ByteArrayDataSource(compressed, "application/xml",fileName);
message.addOutboundAttachment(attachmentName, new DataHandler(attachment))

return payload;]]></scripting:script>
        </scripting:component>
        <copy-attachments attachmentName="*" doc:name="All attachments together"/>
        <set-payload value="#[null]" doc:name="Nullify Payload"/>
        <logger message="before ingestion call: ${http.by.ingestion.basepath}, ${http.by.ingestion.host}, ${http.by.ingestion.port}" level="DEBUG" doc:name="Log Ingestion basepath, host, port"/>
        <logger message="Begin Posting #[flowVars.Category] for Part: #[flowVars.partId]" level="INFO" doc:name="Begin Posting data"/>
        <flow-ref name="Ingestion_with_retries_Flow" doc:name="Flow Ref Ingestion_with_retries" doc:description="retry injestion api call"/>
</sub-flow>

<flow name="Ingestion_with_retries_Flow" >
        <until-successful objectStore-ref="objectStore" maxRetries="${max.retries}" deadLetterQueue-ref="Failed_Payload_To_ErrorDir_And_Notify"
                          failureExpression="#[(exception != null) and (exception.causedBy(java.net.ConnectException) || exception.causedBy(java.net.SocketTimeoutException) || exception.causedBy(java.net.SocketException) || exception.causedBy(java.io.IOException))]"
                          doc:name="Until Successful" millisBetweenRetries="${millis.between.retries}">
            <processor-chain doc:name="Processor Chain">
                <logger message="Posting data to Server" level="INFO" doc:name="Logger"/>
                <http:request config-ref="HTTPS_Ingestion_Service_ExtSystem" path="/delivery" method="POST" doc:name="ExtSystem Data Delivery Post">
                    <http:request-builder>
                        <http:header headerName="Accept" value="${http.by.interface.version}"/>
                        <http:header headerName="Content-Encoding" value="gzip"/>
                    </http:request-builder>
                    <http:success-status-code-validator values="200"/>
                </http:request>

                <json:xml-to-json-transformer doc:name="XML to JSON"/>
                <flow-ref name="Subflow_Extract_Ingestion_Response" doc:name="Extract Ingestion Response"/>
            </processor-chain>
        </until-successful>
</flow>

<sub-flow name="Subflow_Extract_Ingestion_Response">
        <object-to-string-transformer returnClass="java.lang.String" mimeType="application/json" doc:name="Response_to_String"/>

        <dw:transform-message doc:name="Extract DeliveryId">
            <dw:set-payload resource="classpath:ingestion\ingestion-delivery.dwl"/>
        </dw:transform-message>
        <json:json-to-object-transformer returnClass="java.lang.Object" doc:name="JSON to Object"/>
        <set-variable variableName="ExtSystemDeliveryID" value="#[payload.DeliveryID]" doc:name="ExtSystemDeliveryID"/>
        <logger message="Delivery ID: #[payload.DeliveryID]" level="INFO" doc:name="Log Delivery Id"/>
        <set-variable variableName="ExtSystemStatus" value="#[payload.Status]" doc:name="ExtSystemStatusStatus"/>
        <flow-ref name="Update_DeliveryID_Category_in_Part_Flow" doc:name="Update Part with DeliveryID and Category"/>
        <set-payload value="#[payload + '\n']" doc:name="Set Payload"/>
        <file:outbound-endpoint path="${write.folderpath}#[flowVars.correlationId]" outputPattern="HttpResponse_IngestionIDs.txt" connector-ref="File" responseTimeout="10000" doc:name="Write Ingestion Response"/>
        <logger message="Ingestion response stored at ${write.folderpath}#[flowVars.batchJobInstanceId]/#[flowVars.Category]_#[flowVars.partId].gz" level="INFO" doc:name="Log response path"/>
 </sub-flow>

Mule 4.1.4 XML压缩文件上传逻辑

<flow name="storeStocksFlow" doc:id="2d611c4c-edec-4b75-aa94-25474d145040" >
        <http:listener doc:name="POST/payloadtest" doc:id="a5ed0fce-aa12-4e00-a68c-fe99008f1559" allowedMethods="POST" config-ref="HTTP_Listener_config" path="/payloadtest" outputMimeType="application/json">
        </http:listener>
        <logger level="INFO" doc:name="Logger" doc:id="61545cb4-8d94-4af8-a08e-9bfd0667b77f" message="Input json request: #[payload]"/>
        <set-variable value="#[payload]" doc:name="Set Variable" doc:id="3923534b-7482-4a8c-ad46-948fda597550" variableName="origJsonInPayload"/>       
        <set-variable value="#[uuid()]" doc:name="Set Variable correlationId" doc:id="49798fd3-3175-44f8-9443-368b9a018207" variableName="correlationId"/>
        <logger level="INFO" doc:name="Logger before transformation" doc:id="c72a768f-58c4-4947-b29c-93aa955b18a5" message="Before transformation: #[payload]"/>
        <logger level="INFO" doc:name="Logger after transformation" message="Logger after transformation: #[payload]" doc:id="287ee190-47f6-4af6-982e-6f93a66cc052"/>
        <!-- Tried both compressed and plain xml format both giving BAD_REQUEST error
        <compression:compress doc:name="Gzip Compress" doc:id="bf8e4d8e-dbce-43f8-982a-ff68b87839c0" >
            <compression:compressor >
                <compression:gzip-compressor />
            </compression:compressor>
        </compression:compress> -->
        <logger message="gzip compression completed - payload:#[payload]" level="INFO" doc:name="gZip completed" />
        <set-variable variableName="fileContentgzip" value="#[payload]" doc:name="fileContentgzip" />
        <set-variable variableName="TenantID" value="#['${http.ext.system.tenant}']" mimeType="application/json" doc:name="Tenant ID"/>
        <set-variable variableName="Category" value="Stocks" mimeType="application/json" doc:name="Category"/>
        <set-variable variableName="Data" value="#[vars.fileContentgzip]" mimeType="application/xml" doc:name="Data"/>
        <logger level="INFO" doc:name="Logger" doc:id="29a22776-354e-42b0-b486-36bedcf8d6f0" message="JOB entry created in JOB table."/>
        <flow-ref name="BY_API_Call_SubFlow1" doc:name="ExtSystem Ingestion API Test"/>
 </flow>

 <sub-flow name="API_Call_SubFlow1">
        <logger message="Posting data to Server" level="INFO" doc:name="Logger" />
        <http:request config-ref="HTTPS_Ingestion_Service_ExtSystem" path="/delivery" method="POST" doc:name="Ext System Data Delivery Post" outputMimeType="application/xml">
            <http:body><![CDATA[#[%dw 2.0
output application/xml
input payload multipart/form-data
---
{
  parts : {
    Data : {
      headers : {
        "Content-Disposition" : {
          "name" : "Data",
          "filename": "Stocks.xml"
        },
        "Accept" : 'application/xml',
        "Content-Encoding": 'gzip',
        "TenantID": "xxxx-yyyy-aaaa-bbbb-ccccccc",
        "Category": "Stocks"
      },
      content : payload
    }
  }
}]]]></http:body>
            <http:headers ><![CDATA[#[output application/java
---
{
    "Content-Type" : "application/com.ext-system.xxx_and_yyy-v1.14.17+xml"
}]]]></http:headers>
            <http:response-validator >
                <http:success-status-code-validator values="200" />
            </http:response-validator>
        </http:request>
        <logger level="INFO" doc:name="Ingestion API Response" doc:id="a9ece74e-4b86-486f-9f3c-16272d1d00d1" message="Ingestion API Response: #[payload]"/>
</sub-flow>

错误日志:

0-6ffbd441-5963-11e9-8d2b-0a0027000005] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: Posting data to Server
ERROR 2019-04-08 00:02:04,461 [[MuleRuntime].cpuLight.16: [adapter].storePersonFlow.CPU_LITE @427b75e6] [event: ] org.mule.runtime.core.internal.exception.OnErrorContinueHandler: 
********************************************************************************
Message               : HTTP POST on resource 'https://api.ext-system.com:443/xxxx/delivery' failed: bad request (400).
Error type            : HTTP:BAD_REQUEST
Element               : API_Call_SubFlow1/processors/1 @ adapter:exposing-a-restful-resource-using-the-http-connector.xml:142 (Ext System Data Delivery Post)
Element XML           : <http:request config-ref="HTTPS_Ingestion_Service_ExtSystem" path="/delivery" method="POST" doc:name="Ext System Data Delivery Post" outputMimeType="application/xml">
<http:body>#[%dw 2.0
output application/xml
input payload multipart/form-data
---
{
  parts : {
    Data : {
      headers : {
        "Content-Disposition" : {
          "name" : "Data",
          "filename": "Stocks.xml"
        },
        "Accept" : 'application/com.ext-system.xxx_and_yyy-v1.14.17+xml',
        "Content-Encoding": 'gzip',
        "TenantID": "xxxx-yyyy-aaaa-bbbb-ccccccc",
        "Category": "Stocks"
      },
      content : payload
    }
  }
}]</http:body>
<http:headers>#[output application/xml
---
{
    "Content-Type" : "application/com.ext-system.xxx_and_yyy-v1.14.17+xml"
}]</http:headers>
<http:response-validator>
<http:success-status-code-validator values="200"></http:success-status-code-validator>
</http:response-validator>
</http:request>

  (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

INFO  2019-04-08 00:02:04,466 [[MuleRuntime].cpuLight.16: [adapter].storePersonFlow.CPU_LITE @427b75e6] [event: 0-6ffbd441-5963-11e9-8d2b-0a0027000005] org.mule.runtime.core.internal.processor.LoggerMessageProcessor: In HTTP:BAD_REQUEST
mule-component anypoint-studio mule-esb mule4
2个回答
1
投票

主机返回错误,因为它不喜欢请求。通过查看代码片段很难理解可能出现的问题。完整图片重新查询以了解失败的服务器验证的数据和详细信息。

如果您有一个工作案例(3.9版本),解决此问题的方法是在两个版本中启用HTTP线路日志(https://support.mulesoft.com/s/article/How-to-Enable-HTTP-Wire-Logging),执行它们并比较两个HTTP请求。然后你可以看到它们之间有什么不同,并调整Mule 4版本以匹配其他请求。


0
投票

我得到了根本原因,请求中缺少标头,我可以在log4j2.xml中启用DEBUG后跟踪这个,如alejandro-dobniewski建议的那样。在我的用例TenantID中,Category(这两个键的值都是String)和Data是作为multipart / form-data一部分的键。数据值将是gzip文件内容。 json下面是自我解释的。

解:

HTTP请求的标头和正文(重要的是部件有效负载json)的正确格式是:

<http:body ><![CDATA[#[%dw 2.0
output multipart/form-data
---
{
  parts: {
    TenantID : {
      headers : {
        "Content-Type": "text/plain"
      },
      content : "xxxxxxxxx"
    },
    Category : {
      headers : {
        "Content-Type": "text/plain"
      },
      content : "MyCategory"
    },
    Data: {
      headers: {
        "Content-Disposition": {
          "name": "Data",
          "filename": "MyCategory_gzip"
        },
        "Content-Type": payload.^mimeType,
      },
      content: payload
    }
  }
}]]]></http:body>
            <http:headers ><![CDATA[#[output application/java
---
{
    "Accept" : "application/com.xxxxx-v1.1+xml",
    "Content-Encoding" : "gzip"
}]]]></http:headers>
© www.soinside.com 2019 - 2024. All rights reserved.