Modify form-data Request body - Add new Key-Value

We have an use case where were receive form-data payload with multiple key value pairs. I need extract value from one key, create an json object and assign it to new Key. 
New payload should have the existing values along with the new one.

Example:

adithyaseelam_0-1687747975482.png

 

adithyaseelam_2-1687747679195.png

 

 

From the above screen shot. I need to extract value of Sample Key which is an json object and create a new Key Sample2 in the below json format. 

 

{                
"Trace-Id": "abc123ABC",
"Time": "{client.received.end.timestamp}",
"Payload": ["{Sample Value}"]
}  

 

My Final req going to target system should look like below snapshot.

adithyaseelam_3-1687747742399.png

 

 

Solved Solved
1 7 1,708
1 ACCEPTED SOLUTION

If I were you I would set the debug property to true, and then examine the trace, to see the call stack when the exception is thrown. javax.json.JsonValue is a class that is used inside the callout, for parsing JSON.  I don't know why it would be giving that error. Your configuration works for me. 

Do you have the two required dependency jars in your proxy bundle? 

  • javax.json-api-1.1.4.jar
  • javax.json-1.1.4.jar

 

View solution in original post

7 REPLIES 7

I think what you are hoping to do is.... Configure an Apigee API Proxy to accept a multi-part form request, which contains 3 parts. One part is a JSON payload and the other 2 parts are "attachments" which happen to be PDF files. You want the proxy to extract and then modify the JSON payload, then re-assemble the modified JSON payload into a multi-part form again, along with the original two attachments (unchanged).

IF that's the case, then I think you can do that manipulation using the Multipart form callout:

  • first, invoke the Java callout (MultipartFormParserV2) to parse the form and extract the parts,
  • then use a JavaScript callout to do the modification on your JSON payload
  • then invoke the Java callout (MultipartFormCreatorV2) to create a new multi-part message, using the modified JSON payload

The MultipartFormParserV2 will produce a couple byte arrays that contain the attachments. You can pass those as inputs to the MultipartFormCreatorV2 to create the form. 

@dchiesa1 Thanks for the response.
Yes, I need to extract the first multi-part form key value(which is a JSON). Using the extracted value (JSON), I need to create 4th multi-part form(Eg Sample 2) in below format. 

{                
"Trace-Id": "abc123ABC",
"Time": "{client.received.end.timestamp}",
"Payload": ["{First multi-part Value(JSON)}"]
}  

 My final req going to target system looks like below snap shot.

adithyaseelam_0-1687886813751.png

 

OK, and did you try it? Did it work?

@dchiesa1 
Am using below java callout to extract value from req and seeing below error 

 

 

<JavaCallout continueOnError="false" enabled="true" name="Java-Callout-1">
    <Properties>
        <Property name="source">message</Property>
        <Property name="debug">true</Property>
    </Properties>
    <ClassName>com.google.apigee.callouts.MultipartFormParserV2</ClassName>
    <ResourceURL>java://apigee-multipart-form-20230117.jar</ResourceURL>
</JavaCallout>

 

 

message should have all the request content including headers and payload as per the documentation.

Error:

mpf_exception : java.lang.IllegalStateException: contentType must not be null
mpf_error  : contentType must not be null

 In request I have all the required values given in documentation. 

content-length : 1003964
content-type : multipart/form-data; boundary=--------------------------185623916636805336267638
Request Body:
----------------------------185623916636805336267638 Content-Disposition: form-data; name="Sample" {
JSON Payload
}

I also tried with the sample bundle in repo. Its also giving me the same error

adithyaseelam_0-1687998789918.pngadithyaseelam_1-1687998833799.png


Please let me know if am using it in right way?

You are using it in the right way.  But... there is a bug in the 20230117 version of the callout, which did not handle parts which lacked a content-type header. 

I've updated the callout, and I believe it should work for you now. Can you "git pull" and give it another try? 

I got the latest code from the repo and now its working. 
Thanks for fixing the bug @dchiesa1 

Now am seeing another issue.
From the example below. 

 

Request Body:
----------------------------185623916636805336267638
Content-Disposition: form-data; name="Sample"
{
JSON Payload
}

 

Extracted JSON from Sample and created another JSON object in the required below format.

 

{                
"Trace-Id": "abc123ABC",
"Time": "{client.received.end.timestamp}",
"Payload": ["{Sample JSON (First multi-part Value)}"]
} 

 

Now am trying to create a new multi-part message called ENVELOPE with the modified JSON using MultipartFormCreatorV2.

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<JavaCallout continueOnError="false" enabled="true" name="JC-MultiFormRequest">
    <DisplayName>JC-MultiFormRequest</DisplayName>
    <Properties>
        <Property name="descriptor">
    {
      "ENVELOPE" : {
        "content-var" :  "EnvelopeStr",
        "content-type" : "application/json",
        "want-b64-decode": false
      }
    }
    </Property>
    </Properties>
    <ClassName>com.google.apigee.callouts.MultipartFormCreatorV2</ClassName>
    <ResourceURL>java://apigee-multipart-form-20230628.jar</ResourceURL>
</JavaCallout>

 

JavaCallout is giving the error.

 

 

{
    "fault": {
        "faultstring": "Failed to execute JavaCallout. javax/json/JsonValue",
        "detail": {
            "errorcode": "steps.javacallout.ExecutionError"
        }
    }
}

error.class 	com.apigee.kernel.exceptions.spi.UncheckedException
state 	TARGET_REQ_FLOW
type 	ErrorPoint
error 	Failed to execute JavaCallout. javax/json/JsonValue
Identifier 	fault

 

Also could you please send sample code on how to pass inputs to the MultipartFormCreatorV2 to create the form.
In our case we will have n number of attachments coming as part of the actual request.

 

If I were you I would set the debug property to true, and then examine the trace, to see the call stack when the exception is thrown. javax.json.JsonValue is a class that is used inside the callout, for parsing JSON.  I don't know why it would be giving that error. Your configuration works for me. 

Do you have the two required dependency jars in your proxy bundle? 

  • javax.json-api-1.1.4.jar
  • javax.json-1.1.4.jar