vbhanuchander-lang opened a new pull request, #7770:
URL: https://github.com/apache/hop/pull/7770

   Addresses #6408.
   
   The Kafka transforms expose key, message, topic, partition, offset and 
timestamp, but not the record headers — so anything carried in a header (trace 
context, schema hints, routing or tenancy metadata) is unreachable on the way 
in and impossible to set on the way out. As the reporter put it, that rules Hop 
out of a fair number of Kafka use cases.
   
   This adds headers to both sides.
   
   ### Exchange format
   
   A record carries an **ordered list** of header pairs and the **same name may 
appear more than once**, neither of which a flat row column can express. The 
value is therefore a JSON array of `{"name":..,"value":..}` objects rather than 
a JSON object:
   
   ```json
   
[{"name":"traceparent","value":"00-abc"},{"name":"tag","value":"one"},{"name":"tag","value":"two"}]
   ```
   
   A JSON object would have been friendlier to hand-write, but it silently 
drops repeats and loses ordering. The array is lossless, which means the 
consumer's output can be fed straight into the producer's *Headers field* and 
the headers come out unchanged — including a null value, which stays distinct 
from an empty one.
   
   Both directions live in one new `shared/KafkaHeaders` class rather than in 
either transform, because the format is a contract *between* them; keeping them 
together is what stops them drifting apart. The round trip is covered by a test.
   
   ### Consumer
   
   A new optional **headers** output field. It ships with an **empty output 
name**, and `getRowMeta` already omits fields without one, so a pipeline saved 
before this change produces exactly the row it did before. Give it a name to 
start reading headers.
   
   ### Producer
   
   A new optional **Headers field**. Left empty, messages are sent without 
headers, so existing pipelines are unaffected. A field that is named but 
missing from the input stream fails when the first row arrives — matching how 
the key, message and topic fields already behave — and a value that is not a 
JSON array of name/value objects fails with the offending document in the 
message.
   
   ### Two things I had to fix to make this work
   
   **The consumer's row builder used fixed indices.** `putFieldOnRowMeta` omits 
any field whose output name is empty, so the output row is variable length, but 
`processMessageAsRow` wrote its six values at indices 0–5 regardless. Clearing 
the name of, say, the topic field was enough to shift every later column by 
one. Values are now placed only for fields that contribute a column, in the 
order `getRowMeta` adds them. That is a pre-existing defect rather than 
anything this feature introduced, but an optional field cannot sit on top of 
fixed indices, so it had to be fixed here.
   
   **The consumer's output field table was read-only.** It was already built 
with an editable name column and a `setDisabledListener` restricting type 
changes to key/message, but the table itself was flagged `setReadonly(true)` 
and the write-back left as `// meta.setField(field); TODO FIXME`, so field 
names could not actually be changed from the dialog. That would have left the 
new Headers field impossible to switch on except through metadata injection. 
The write-back is now implemented and the table editable — which the indexing 
fix above makes safe, since clearing a name now correctly drops the column 
instead of corrupting the row.
   
   Happy to split either of those into their own PR if you would rather keep 
this one to the feature.
   
   ### Tests
   
   15 cases in `KafkaHeadersTest` covering rendering, parsing and the round 
trip: ordering, repeated names, null vs. empty values, JSON escaping, 
non-ASCII, and the rejection cases (not JSON, a JSON object, an entry without a 
name). Plus the existing suite — 32 tests pass in the module.
   
   `mvn -pl plugins/transforms/kafka test`, `spotless:check` and 
`apache-rat:check` (Unapproved: 0) all pass.
   
   ### Documentation
   
   Both `kafkaconsumer.adoc` and `kafkaproducer.adoc` are updated, including a 
note that an empty output name keeps a field off the row.
   
   ### Not included
   
   I have not added an integration test under `integration-tests/kafka` for 
this one yet — happy to add a produce-with-headers / consume-and-assert 
workflow in the same shape as `0004-kafka-test-topic-from-field` if you would 
like it before merge.
   
   ------------------------
   
   Thank you for your contribution! Follow this checklist to help us 
incorporate your contribution quickly and easily:
   - [x] Run `mvn clean install apache-rat:check` to make sure basic checks 
pass. A more thorough check will be performed on your pull request 
automatically. *(ran the module build, `spotless:check` and `apache-rat:check`; 
full `clean install` not run locally)*
   - [x] If you have a group of commits related to the same change, please 
squash your commits into one and force push your branch using `git rebase -i`. 
*(two commits kept deliberately: read side, then write side — happy to squash)*
   - [x] Mention the appropriate issue in your description (for example: 
`addresses #123`), if applicable.
   
   To make clear that you license your contribution under the [Apache License 
Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0)
   you have to acknowledge this by using the following check-box.
   
   - [x] I hereby declare this contribution to be licensed under the [Apache 
License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0)
   - [ ] In any other case, please file an [Apache Individual Contributor 
License Agreement](https://www.apache.org/licenses/icla.pdf).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to