oscerd opened a new pull request, #28970:
URL: https://github.com/apache/camel/pull/28970

   Fixes [CAMEL-26251](https://issues.apache.org/jira/browse/CAMEL-26251), 
found while adding the catalog body types (CAMEL-24961).
   
   ## 1. The connectionFactory option of the component was ignored
   
   **Was:** `GoogleBigQueryComponent` and `GoogleBigQuerySQLComponent` have a 
`connectionFactory` option, but `createEndpoint` copied only the 
`configuration` of the component, and the endpoints read only 
`configuration.getConnectionFactory()`. `component.setConnectionFactory(...)` 
was ignored without a word: each endpoint built a default client from its own 
options.
   
   **Now:** `createEndpoint` gives the endpoint configuration the factory of 
the component when it has none. A `connectionFactory` set on the endpoint URI 
still wins, as it is applied after. The factory is set when the endpoint is 
created rather than read in `doStart`, so an explicit component option also 
wins over the autowiring of the endpoint option (a single factory bean in the 
registry), which only fills an empty option.
   
   ## 2. bigquery-sql: a DDL statement failed with a NullPointerException
   
   **Was:** `GoogleBigQuerySQLProducer` assigned `getNumDmlAffectedRows()` to a 
`long` for every statement that is not a SELECT. BigQuery gives no such count 
for DDL (`CREATE TABLE`, `DROP TABLE`), so the unboxing threw a 
NullPointerException after the statement had run.
   
   **Now:** the count is a `Long`, and the body is null when BigQuery gives 
none. I chose null over 0: a DML statement that changes no row gives 0, so 0 
would not tell the two apart, while null says that the statement has no count.
   
   ## 3. bigquery: a bad entry of a grouped exchange was silently dropped
   
   **Was:** for a body that is not a `Map` or a `List`, the producer set the 
"Cannot handle body type" exception on the exchange of that entry. For a 
grouped exchange this is an exchange of the group, which nobody looks at: the 
grouped exchange completed as a success, the other rows were inserted, and the 
bad entry was lost without notice.
   
   **Now:** the producer checks all the bodies before it sends any row. When 
one is not a row, the exception is set on the exchange being processed, and 
nothing is inserted, also when the rows go to several tables (the producer 
sends one request per table, suffix and partition, so it could have sent some 
before it reached the bad entry). This matches how the producer reports its 
other errors, which fail the whole exchange: a missing table id, and insert 
errors (BigQuery fails a whole request with an invalid row, as 
`skipInvalidRows` is not set). For a grouped exchange the message says which 
entry, such as `Cannot handle body type java.lang.String (exchange 2 of 2 of 
the grouped exchange, so no row of the group is inserted)`. A single exchange 
keeps the message it had.
   
   ## Tests
   
   - New `GoogleBigQueryComponentConnectionFactoryTest` (4 tests): for 
google-bigquery and google-bigquery-sql, the endpoint gets the factory of the 
component (a factory over a mocked `BigQuery`), and the insert or the query 
goes to the mocked client; a `connectionFactory` on the endpoint wins over the 
one of the component. Each test checks the factory before it sends anything, so 
a default client never gets a call.
   - New `GoogleBigQuerySQLProducerStatementTest` (2 tests, with the mocked 
`BigQuery`, `Job` and statistics of the other SQL tests): a `CREATE TABLE` 
gives no body, and a DML statement that changes no row gives 0.
   - `GoogleBigQueryProducerBodyTypeTest`: 3 more tests. The rows of a grouped 
exchange go in one request; a bad body fails the grouped exchange and nothing 
is inserted; nothing is inserted either when the bad body goes to another table 
than the rows before it.
   - With the `src/main` changes reverted, 5 of the 9 new tests fail, each on 
the bug: the endpoint has a default factory instead of the one of the component 
(2), the grouped exchange has no exception (2), and the DDL statement throws 
the NullPointerException of the issue (1). The 4 that pass guard behaviour that 
was already right: the factory of the endpoint winning over the one of the 
component (2), the rows of a grouped exchange in one request, and 0 for a DML 
statement that changes no row.
   - Module: 56 tests, 0 failures (1 skipped, as before).
   
   ## Docs and generated files
   
   - google-bigquery doc: a body that is not a row fails, and for a grouped 
exchange none of its rows is inserted. google-bigquery-sql doc: other 
statements, such as DDL, give no body.
   - `@BodyTypes`: the google-bigquery `producerIn` description says what a bad 
body of a grouped exchange does; the google-bigquery-sql `producerOut` carriers 
add null, also with `outputType=STREAM_LIST`, and the description says when.
   - The regenerated `google-bigquery.json` and `google-bigquery-sql.json` 
(body types only) and both docs are copied into the catalog.
   - Upgrade guide entries for 4.24: the grouped exchange that fails as a 
whole, and the `connectionFactory` of the component that is now used. None for 
the DDL fix: a NullPointerException becomes a working call.
   
   ## Not changed
   
   - For item 3, the other choice was to set the exception on the grouped 
exchange and still insert the good rows. A redelivery or a retry of the grouped 
exchange would then insert those rows again (BigQuery keeps both copies without 
an insert id), so the exchange fails before anything is sent. **Open 
question:** if users want the good rows kept, should that be an option, like 
the `skipInvalidRows` of BigQuery, rather than the default?
   - A `List` body whose elements are not `Map` objects still fails with a 
`ClassCastException` while the request is built: a failure, not a silent drop, 
and not in the issue.
   - The `projectId` and `datasetId` options of `GoogleBigQueryComponent`, and 
`projectId` of `GoogleBigQuerySQLComponent`, are not used by the endpoints 
either: they take these from the URI path. Not in the issue, so unchanged.
   
   Main only, as the other fixes of the CAMEL-24961 follow-ups.
   
   _Claude Code on behalf of Andrea Cosentino (oscerd)_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
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]

  • [PR] CAMEL-26251: camel-googl... oscerd (via GitHub) via commits

Reply via email to