Raymond created CAMEL-22963:
-------------------------------
Summary: [camel-api] Get Exchange as Json
Key: CAMEL-22963
URL: https://issues.apache.org/jira/browse/CAMEL-22963
Project: Camel
Issue Type: Wish
Components: came-core
Affects Versions: 4.17.0
Reporter: Raymond
With the log data component, you can get the data from an exchange. The output
looks something like this:
{code:java}
Exchange[ Headers: {breadcrumbId=97D358D813160DB-000000000000002D,
CamelServletContextPath=/tst, ComponentInitTime=1770306467630,
Connection=close} BodyType: org.apache.camel.converter.stream.InputStreamCache
Body: <persons> <person> <name>John Doe</name> </person> <person> <name>Jane
Doe</name> </person> </persons> ]
{code}
This is nice, and you can even customize is it using a custom
exchangeFormatter.
I would like to get the exchange data as JSON programmatically from the
Exchange API. Similarly, as how to get/dump route stats as JSON (on the
ManagedRouteMBean).
The methods could be added to regular Exchange api, or to the extended exchange
api (ExchangeExtension()).
*Example methods:*
1. exchange.getAsJson()
This would get the full exchange as JSON.
2. exchange.getAsJson(includeProperties, includeVariables, includeException,
includeHeaders, includeAttachment, includeeBodyType, includeBody)
This would give the developer fine grain control of what the JSON contains.
3. exchange.get(exchangeFormatter);
This allows to use as custom exchangeFormatter to get the data, which can be as
JSON or formatted in some other way.
I used here exchange.getAsJson(), but the method could be called
exchange.dumpAsJson() as well (in accordance with how other methods are when
'dumping' data).
Probably, the JSON could be created with exchangeFormatter and the
camel-util-json. An example of the output:
{code:java}
{
"exchange": {
"timestamp": "2025-03-17T15:08:40.085+0000",
"exchangeId": "C6D8944F2120FA5-0000000000000000",
"groupId": "orders",
"routeId": "64f0a356a810a200c4000684",
"fromRouteId": "8934a56a810a200c4000270",
"pattern": "InOut",
"properties": {
"myProperty1": "myPropertyValue",
"myProperty2": "myPropertyValue2"
},
"variables": {
"myVariable": "myVarValue",
"myVariable2": "myVarValue2"
},
"exception": {
"cause": "Some cause"
},
"message": {
"headers": {
"Accept":
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Priority": "u=0, i",
"Connection": "keep-alive",
"breadcrumbId": "C6D8944F2120FA5-0000000000000000",
"Upgrade-Insecure-Requests": "1",
"CamelServletContextPath": "/test",
"Content-Type": "text/plain"
},
"attachments": {
"attachement": "key1",
"attachement": "key2"
},
"bodyType": "java.lang.String",
"body": "My Test Body"
}
}
} {code}
*Sidenote 1: Getting properties/variables/headers*
Maybe the following ticket "Exchange getPropertyAsList, getPropertyAsMap":
https://issues.apache.org/jira/browse/CAMEL-22910
can be of help.
*Sidenote 2: maxChars*
Like in the log data component it maybe useful to set the maxChars for values
such as the body, headers, variables, properties. **
*Sidenote 3: Object types*
In the example I included the bodyType (type of object) however there maybe
cases where the object type is also useful for headers/properties/variables. **
*Side note 4: Meta information*
For our platform we already created a JSON that works like this:
1. Collect event with the EventNotifier
2. Turn exchange data into a json
3. Send/Offload json to a database (for example ElasticSearch)
The reason is that with observability you get a lot of metrics, but most users
like to have more insight in the content of messages as well. The JSON we
create looks like this:
{code:java}
{
"exchangeId": "C6D8944F2120FA5-0000000000000000",
"breadCrumbId": "C6D8944F2120FA5356654",
"groupId": "orders",
"routeId": "64f0a356a810a200c4000684",
"previousRouteId": "64f0a356a810a200c4000684",
"fromRouteId": "8934a56a810a200c4000270",
"stepId": "64f0a356a810a200c4000684_3256",
"failedExchange": false,
"timestamp": "2025-03-17T15:08:40.085+0000",
"expiryDate": "2025-03-17T16:08:40.086+0000",
"body": "aGVsbG8gd29ybGQ=\r\n",
"headers": {
"Accept":
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Priority": "u=0, i",
"Connection": "keep-alive",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0)
Gecko/20100101 Firefox/136.0",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Site": "none",
"Host": "localhost:9001",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Sec-Fetch-Mode": "navigate",
"breadcrumbId": "C6D8944F2120FA5-0000000000000000",
"CamelServletContextPath": "/test",
"Sec-Fetch-User": "?1",
"Accept-Language": "en-US,en;q=0.5",
"Content-Type": "text/plain"
},
"metadata": [{
"unit": "",
"name": "ExchangePattern",
"value": "InOut"
}, {
"unit": "ISO 8601",
"name": "Timestamp",
"value": "2025-03-17T16:08:40.086+0000"
}, {
"unit": "long",
"name": "UnixTimestamp",
"value": "1770305720"
}, {
"unit": "milliseconds",
"name": "ResponseTime",
"value": "4"
}, {
"unit": "object",
"name": "BodyType",
"value": "InputStreamCache"
}, {
"unit": "bytes",
"name": "BodySize",
"value": 18
}, {
"unit": "bytes",
"name": "HeadersSize",
"value": 566
}
],
} {code}
Some remarks:
1. BreadCrumbId: We include the breadcrumb id as "transaction ID" to track
messages.
2. We also include the previousRouteId and previousStepId so we can show the
flow of the message.
3. We convert all values to String if possible to make them readable in the
frontend.
4. We include an expiryDate. This date shows how long the exchange needs to be
persistent in the database before deletion.
5. Metadata: We include metadata such as the size of the body and headers, Unix
timestamp, timestamp in nanoseconds (to order the messages), responseTime (how
long it took for a route to process the exchange). This metadata helps the user
get more insight.
------------------------------------------------------
Formalizing a JSON format is practically for external tools or users to read a
Camel exchange would be a great enhancement. It can be used for debugging,
tracing purposes and more.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)