I want to pass a payload with Content-Type application/json-patch+json from wso2 to an external api. I tried setting this as a transport header property, but it goes as application/json and not the type i want.
<header name="Content-Type" scope="transport" value="application/json-patch+json"/>
I have also set the following property in axis2.xml file
<messageBuilder contentType="application/json-patch+json"
class="org.wso2.micro.integrator.core.json.JsonStreamBuilder"/>
Can someone help me with this, i cannot figure out how to send the correct content type.
Update
This is the proxy i am using :-
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="TestProxy" startOnLoad="true" transports="http https vfs" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<clone sequential="true">
<target>
<sequence>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<payloadFactory media-type="json">
<format>
[
{
"op":"add",
"path":"/example/path",
"value":{
"attributes": "test-attribute"
}
]
</format>
<args/>
</payloadFactory>
<property name="ContentType" value="application/json-patch+json" scope="axis2"/>
<property name="Content-Type" value="application/json-patch+json" scope="transport"/>
<log>
<property name="test-payload" expression="json-eval($)"/>
</log>
<property expression="fn:concat('Bearer ','**xyz**')" name="Authorization" scope="transport" type="STRING"/>
<call>
<endpoint>
<http method="patch" uri-template="https://api/v1/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<log>
<property expression="json-eval($)" name="patch-response"/>
</log>
</sequence>
</target>
<target>
<!-- some other logic -->
</target>
</clone>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
</proxy>
these are the logs:-
[2023-03-28 10:46:18,155] DEBUG {headers} - http-outgoing-1 >> PATCH /api/v1/test HTTP/1.1
[2023-03-28 10:46:18,155] DEBUG {headers} - http-outgoing-1 >> Authorization: Bearer **xyz**
[2023-03-28 10:46:18,155] DEBUG {headers} - http-outgoing-1 >> activityid: f6fabf50-e480-4f71-aacb-c8b8abe3e376
[2023-03-28 10:46:18,155] DEBUG {headers} - http-outgoing-1 >> Accept: */*
[2023-03-28 10:46:18,160] DEBUG {headers} - http-outgoing-1 >> contentType: application/json-patch+json
[2023-03-28 10:46:18,160] DEBUG {headers} - http-outgoing-1 >> Content-Type: application/json
[2023-03-28 10:46:18,160] DEBUG {headers} - http-outgoing-1 >> SOAPAction:
[2023-03-28 10:46:18,160] DEBUG {headers} - http-outgoing-1 >> Transfer-Encoding: chunked
[2023-03-28 10:46:18,163] DEBUG {headers} - http-outgoing-1 >> Connection: Keep-Alive
[2023-03-28 10:46:18,163] DEBUG {headers} - http-outgoing-1 >> User-Agent: Synapse-PT-HttpComponents-NIO
[2023-03-28 10:46:18,192] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "PATCH /api/v1/test HTTP/1.1[\r][\n]"
[2023-03-28 10:46:18,192] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "Authorization: Bearer **xyz**[\r][\n]"
[2023-03-28 10:46:18,192] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "activityid: f6fabf50-e480-4f71-aacb-c8b8abe3e376[\r][\n]"
[2023-03-28 10:46:18,195] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "Accept: */*[\r][\n]"
[2023-03-28 10:46:18,197] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "contentType: application/json-patch+json[\r][\n]"
[2023-03-28 10:46:18,198] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "Content-Type: application/json[\r][\n]"
[2023-03-28 10:46:18,198] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "SOAPAction: [\r][\n]"
[2023-03-28 10:46:18,200] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "Transfer-Encoding: chunked[\r][\n]"
[2023-03-28 10:46:18,200] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "Connection: Keep-Alive[\r][\n]"
[2023-03-28 10:46:18,201] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
[2023-03-28 10:46:18,201] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "[\r][\n]"
[2023-03-28 10:46:18,203] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "236[\r][\n]"
[2023-03-28 10:46:18,203] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "[{"op":"add","path":"/example/path","value":{"attributes":{"test-attribute"}}}][\r][\n]"
[2023-03-28 10:46:18,203] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "0[\r][\n]"
[2023-03-28 10:46:18,203] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 << "[\r][\n]"
[2023-03-28 10:46:18,613] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "HTTP/1.1 200 OK[\r][\n]"
[2023-03-28 10:46:18,613] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "Date: Tue, 28 Mar 2023 05:16:20 GMT[\r][\n]"
[2023-03-28 10:46:18,613] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "Content-Type: application/json[\r][\n]"
[2023-03-28 10:46:18,613] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "Content-Length: 48[\r][\n]"
[2023-03-28 10:46:18,615] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "Connection: keep-alive[\r][\n]"
[2023-03-28 10:46:18,615] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "Vary: Origin[\r][\n]"
[2023-03-28 10:46:18,615] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin[\r][\n]"
[2023-03-28 10:46:18,615] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "X-XSS-Protection: 1; mode=block[\r][\n]"
[2023-03-28 10:46:18,615] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "X-Content-Type-Options: nosniff[\r][\n]"
[2023-03-28 10:46:18,617] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "X-Permitted-Cross-Domain-Policies: master-only[\r][\n]"
[2023-03-28 10:46:18,617] DEBUG {wire} - HTTPS-Sender I/O dispatcher-1 >> "[\r][\n]"
Try setting the following two properties.
<property name="messageType" value="application/json" scope="axis2"/>
<property name="ContentType" value="application/json-patch+json" scope="axis2"/>
Update
The above should actually work. If you have set the messageType property the message will be built as a JSON content and the Content-type header would be picked up from the ContentType
property.
Since it didn't work try to change the message builders and formatters. Message builder is activated when the message comes into MI and Formatters are activated when it's going out. Add the following to the deployment.toml
[[custom_message_formatters]]
class = "org.wso2.micro.integrator.core.json.JsonStreamFormatter"
content_type = "application/json-patch+json"
[[custom_message_builders]]
class = "org.wso2.micro.integrator.core.json.JsonStreamBuilder"
content_type = "application/json-patch+json"
Update 02
Here is a super Simple example that works without changes to the MessageFormatters.
API
<?xml version="1.0" encoding="UTF-8"?>
<api context="/test" name="TestAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" url-mapping="/users">
<inSequence>
<log/>
<payloadFactory media-type="json">
<format>{"message" : "Hello"}</format>
<args/>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2"/>
<property name="ContentType" value="application/json-patch+json" scope="axis2"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Requeset
curl -v --location --request GET 'http://localhost:8290/test/users'
Response
➜ ~ curl --location --request GET 'http://localhost:8290/test/users' -v
Note: Unnecessary use of -X or --request, GET is already inferred.
* Trying 127.0.0.1:8290...
* Connected to localhost (127.0.0.1) port 8290 (#0)
> GET /test/users HTTP/1.1
> Host: localhost:8290
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< activityid: 71c5ecbf-7c7a-4216-873f-85315e58982e
< Accept: */*
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET
< Host: localhost:8290
< Access-Control-Allow-Headers: content-type
< Content-Type: application/json-patch+json; charset=UTF-8
< Date: Mon, 27 Mar 2023 22:37:20 GMT
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
{"message" : "Hello"}%
As you can see the content type is set to < Content-Type: application/json-patch+json;