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]
