wso2wso2-esbwso2-enterprise-integratorwso2-integration-studio

How to post a multipart/form-data File Upload using image URL in WSO2


Need help with the following requirement. 1> get a file from an URL 2> post the file as a multipart/form-data request to a file upload api

For example: the below image url which responds with the google logo

"https://images.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"

to be posted as multipart/form-data request to a file upload api i.e: curl --location 'http://localhost:8290/upload/form'
--form 'companyId="100"'
--form 'companyName="google"'
--form 'website="google.com"'
--form 'file=@"/path/to/file"'

The following script gets the image from an url

<api context="/processFile" name="processFile" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST">
        <inSequence>
            <property expression="$body//url" name="uri.var.fileUrl" scope="default" type="STRING"/>
            <call>
                <endpoint>
                    <http method="get" uri-template="{uri.var.fileUrl}">
                        <suspendOnFailure>
                            <initialDuration>-1</initialDuration>
                            <progressionFactor>-1</progressionFactor>
                            <maximumDuration>0</maximumDuration>
                        </suspendOnFailure>
                        <markForSuspension>
                            <retriesBeforeSuspension>0</retriesBeforeSuspension>
                        </markForSuspension>
                    </http>
                </endpoint>
            </call>
            <respond/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
</api>

However need help to submit the image file as a multipart/form-data request to a file upload api(as in the attached screenshot) in the same process flow.


Solution

  • Here is an example, you may have to adjust the API based on the exact requirement.

    First add the following to the deployment.toml to support retrieving the file.

    [[custom_message_builders]]
    class = "org.wso2.carbon.relay.BinaryRelayBuilder"
    content_type = "image/png"
    

    Then refer the following API to create the Multipart request with the binary payload.

    <?xml version="1.0" encoding="UTF-8"?>
    <api context="/multi" name="MultiPartSample" xmlns="http://ws.apache.org/ns/synapse">
        <resource methods="GET">
            <inSequence>
                <log>
                    <property name="MSG" value="In API"/>
                </log>
                <call>
                    <endpoint>
                        <http method="get" uri-template="https://images.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png">
                            <suspendOnFailure>
                                <initialDuration>-1</initialDuration>
                                <progressionFactor>-1</progressionFactor>
                                <maximumDuration>0</maximumDuration>
                            </suspendOnFailure>
                            <markForSuspension>
                                <retriesBeforeSuspension>0</retriesBeforeSuspension>
                            </markForSuspension>
                        </http>
                    </endpoint>
                </call>
                <payloadFactory media-type="xml">
                    <format>
                        <root xmlns="">
                            <companyId>100</companyId>
                            <companyName>google</companyName>
                            <file filename="something.png" content-type="image/png" >$1</file>
                        </root>
                    </format>
                    <args>
                        <arg evaluator="xml" expression="$body/ns:binary" xmlns:ns="http://ws.apache.org/commons/ns/payload"/>
                    </args>
                </payloadFactory>
                <property name="messageType" scope="axis2" type="STRING" value="multipart/form-data"/>
                <call>
                    <endpoint>
                        <http method="post" uri-template="https://your_seconf_file_upload_api">
                            <suspendOnFailure>
                                <initialDuration>-1</initialDuration>
                                <progressionFactor>-1</progressionFactor>
                                <maximumDuration>0</maximumDuration>
                            </suspendOnFailure>
                            <markForSuspension>
                                <retriesBeforeSuspension>0</retriesBeforeSuspension>
                            </markForSuspension>
                        </http>
                    </endpoint>
                </call>
            </inSequence>
            <outSequence/>
            <faultSequence/>
        </resource>
    </api>
    

    The outcome

    enter image description here