saravanakumar1987 opened a new pull request, #29852: URL: https://github.com/apache/camel/pull/29852
# Description Fixes [CAMEL-26894](https://issues.apache.org/jira/browse/CAMEL-26894). ## What was wrong A component, endpoint or API option of type `java.lang.Boolean` that declares no default value had `"defaultValue": false` in the catalog, and the javadoc of its Endpoint DSL and Component DSL methods said `Default: false`. The value did not come from the option: `EndpointSchemaGeneratorMojo.getDefaultValue` keeps `""` for a `java.lang.Boolean` option that declares no default, and `BaseOptionModel.resolveDefaultValue` turns that `""` into `false`. This is a side effect of [CAMEL-22386](https://issues.apache.org/jira/browse/CAMEL-22386), which made declared boolean defaults JSON booleans instead of strings; before it these options had no default value. In the catalog, 169 component and endpoint options of type `java.lang.Boolean` in 54 components had the default value `false`. 47 of them declare it; the other 122 got it from the generator, and so did 151 API parameters. Such an option is often not `false` when it is not set. For example, two options of `camel-cxf`, both `Boolean` without a declared default: - `allowStreaming`: when it is not set, the endpoint uses the JVM system property `org.apache.camel.component.cxf.streaming`, and allows streaming when that property is not set either. - `wrappedStyle`: when it is not set, CXF chooses the style itself, from the `parameterStyle` of the `@SOAPBinding` annotation, or the wrapped style when there is none. Both showed `Default: false`, which contradicts their descriptions as updated in #29725. ## The change `EndpointSchemaGeneratorMojo` gets a helper, `getOptionDefaultValue`, used at its three call sites of `getDefaultValue`: component options read from setters, `@UriParam` options (which include the options of a nested configuration and the API parameters) and `@UriPath` options. For a `java.lang.Boolean` option without a declared default it returns `null`, so `JsonMapper` writes no default value. Every other option goes through `getDefaultValue` as before. Not changed: - primitive `boolean` options keep `false`; - declared default values, which stay JSON booleans as CAMEL-22386 intended; - headers, models, data formats and languages: `getDefaultValue` itself, `BaseOptionModel.resolveDefaultValue` and `JsonMapper` are unchanged, so for example the route attributes `streamCache`, `trace` and `messageHistory` keep their `false`. Runtime behavior does not change. Only the catalog JSON, the javadoc of the Endpoint DSL and Component DSL, and the option tables of the website (rendered from the JSON) change. The camel-spring-boot starters turn a catalog default into a field initializer, for example `private Boolean allowStreaming = false;` in `CxfComponentConfiguration`, but `CamelPropertiesHelper.copyConfigurationProperties` copies only the options the application configures, so dropping that initializer at the next regeneration of the starters changes nothing either. ## Options that now declare their default Each of the 122 options was classified by the code that reads it. Where the field has an initializer, or the code treats null as `false`, the option now declares that default, so its catalog value stays the same, except for `closeStreamAfterRead`: | Component | Options (component and endpoint unless noted) | Declared | Code that shows the value | |---|---|---|---| | servicenow | `excludeReferenceLink`, `suppressAutoSysField`, `includeScores`, `includeAggregates`, `includeAvailableBreakdowns`, `includeAvailableAggregates`, `includeScoreNotes`, `suppressPaginationHeader`, `inputDisplayValue` | `false` | the field initializers `= false` in `ServiceNowConfiguration.java:70-106` | | azure-storage-datalake | `recursive`, `userPrincipalNameReturned`, `retainUncommitedData`, `close` | `false` | the field initializers `= false` in `DataLakeConfiguration.java:67, 71, 87, 90` | | azure-storage-datalake | `closeStreamAfterRead` | `true` | the field initializer `= true` in `DataLakeConfiguration.java:83`, read by `DataLakeFileOperations.java:97`; the catalog said `false` | | salesforce | `pkChunking` | `false` | `BulkApiProcessor.java:139`: `if (pkChunking != null && pkChunking)` | | undertow | `sendToAll` (endpoint) | `false` | `UndertowProducer.java:91`: `return value != null && value;` | | vertx | `pubSub` (endpoint) | `false` | `VertxEndpoint.java:143`: `return pubSub != null && pubSub;` | The other 90 options, and the 151 API parameters, which are generated and cannot declare a default, now have no default value: <details> <summary>Options and API parameters without a default value, and what happens when they are not set</summary> ### Component and endpoint options (90) - **ai-tool** (component and endpoint): `readOnlyHint`, `idempotentHint`, `destructiveHint`, `openWorldHint`: the hint is not published, and MCP clients apply the defaults of the MCP specification, which are `true` for `destructiveHint` and `openWorldHint`. - **alibaba-sls**: `reverse`: not sent, so the SLS service decides the order. - **amqp** (component): `useTopicPrefix`: when the component builds the connection factory, it sets the `topic://` prefix, as with `true`. `useSsl`: no SSL when the component builds the broker URL, as with `false`, but only an explicit value makes the component build its own connection factory. - **cxf**: `allowStreaming` (component): each endpoint keeps its own value. `allowStreaming` (endpoint): the system property `org.apache.camel.component.cxf.streaming` decides, and streaming is allowed when it is not set either. `wrappedStyle`: CXF decides from the `parameterStyle` of `@SOAPBinding`, and uses the wrapped style when there is none. - **docling** (component and endpoint, ignored in CLI mode): `doOcr`: `enableOCR`, the OCR headers or docling-serve decide. `doTableStructure`: `true` for the structured-data operations, otherwise docling-serve decides. `forceOcr`, `tableCellMatching`, `doCodeEnrichment`, `doFormulaEnrichment`, `doPictureClassification`, `doPictureDescription`, `includeImages`, `abortOnError`: not sent, so docling-serve decides. - **ibm-watsonx-ai** (component and endpoint): `returnDocuments`: `false` when a top N is set, otherwise not sent. `detectPii`, `detectHap`: with both unset, both detectors run; with one set to `false` and the other unset, no detector runs and the operation fails. - **jetty**: `useContinuation`: the component option `useContinuation` decides (`true` by default). - **jpa**: `useExecuteUpdate`: detected from `query` or `nativeQuery`: INSERT, UPDATE and DELETE use `executeUpdate`. - **the 17 `kubernetes-*` and 3 `openshift-*` components**: `trustCerts`: not passed to the fabric8 client, which trusts all certificates only when the kubeconfig, the `kubernetes.trust.certificates` system property or the `KUBERNETES_TRUST_CERTIFICATES` environment variable says so. - **langchain4j-agent** (component and endpoint): `compensateOnToolErrors`, `executeToolsConcurrently`: the `AgentConfiguration` bean decides; an explicit value overrides the bean and requires the inline mode. - **langchain4j-web-search**: `safeSearch`: null is passed to LangChain4j, which turns safe search on. - **log**: `logMask`: the `logMask` of the route, then of the CamelContext applies. - **mina-sftp**: `existDirCheckUsingLs`: deprecated, and mina-sftp does not read it. - **odata**: `count`: no `$count` is sent; an explicit `false` adds `$count=false` to every request. - **salesforce** (component and endpoint): `notifyForOperationCreate`, `notifyForOperationUpdate`, `notifyForOperationDelete`, `notifyForOperationUndelete`: left out of the PushTopic, so a new topic gets the Salesforce default and an existing topic keeps its value. `includeDetails`: no `includeDetails` query parameter, so the Reports API decides. - **servicenow** (component and endpoint): `topLevelOnly`, `favorites`, `key`, `target`: the `sysparm_` parameter is not sent, so the ServiceNow instance decides. - **thymeleaf**: `checkExistence`: the default of the Thymeleaf template resolver (`false`). `cacheable`: the default of the template resolver (`true` for the default `CLASS_LOADER` resolver, `false` for `STRING`). ### API parameters (151 entries, 67 parameters) Camel passes an API parameter on only when it is set (`ApiMethodPropertiesHelper`). - **box**: `files.check`: Camel's `BoxFilesManager` treats null as `false` and does not check for an existing file. `users.force`, `users.notifyUser`: primitive arguments of `deleteUser`, so the call fails with "Missing properties" when they are not set. - **braintree**: `subscription.submitForSettlement`: the `retryCharge` overload without it is called, and the Braintree gateway decides. - **dhis2**: `get.paging`: no paging (null is treated as `false`). `resourceTables.async`: the call waits for the analytics task (null is treated as `false`). `resourceTables.skipAggregate`, `resourceTables.skipEvents`: the query parameter is not sent, so DHIS2 decides. - **fhir**: `read.returnNull`: treated as `false`. `read.throwError`: a plain read (any non-null value, `false` included, throws `NotModifiedException`). `operation.useHttpGet`, `operation.asynchronous`: primitive arguments, so the call fails with "Missing properties" when they are not set. - **google-calendar** (11), **google-drive** (31), **google-mail** (6), **google-sheets** (3): request parameters that Camel sets only when given, so the query parameter is not sent and the Google API default applies. It is `true` for calendar `acl.sendNotifications`, drive `drive-changes.includeRemoved` and `drive-permissions.sendNotificationEmail`; calendar `events.alwaysIncludeEmail` is deprecated and ignored. - **zendesk**: `active`: `getTriggers` and `searchTriggers` are called without the active filter (`false` returns only the inactive triggers). `includeArchived`, `inline`: the overload without the argument passes `false`. `notifySubscribers`: `createArticle` sends no `notify_subscribers`, so Zendesk decides. </details> ## Generated files - 46 component JSON files and their 46 catalog copies: 90 option defaults and 151 API parameter defaults removed; `closeStreamAfterRead` changed to `true` (component and endpoint). - 36 Endpoint DSL files: 234 `Default: false` javadoc lines removed, 6 changed to `Default: true`. - 9 Component DSL files: 31 `Default: false` javadoc lines removed, 1 changed to `Default: true`. The Component DSL also loses one whitespace-only line next to each removed default, because component-builder.vm writes that line only for an option with a default value. The upgrade guide for 4.24 gets an entry, and the sentence of `ai-tool-component.adoc` that mentioned the `defaultValue: false` of the catalog is removed. ## Tests Three new tests in `EndpointSchemaGeneratorMojoTest`, one per call site: endpoint options including a `@UriPath` option (`SomeEndpointWithBooleanOptions`), component options read from setters (`SomeComponentWithBooleanOptions`), and API parameters (`SomeApiWithBooleanOptions`). Each checks that a `java.lang.Boolean` option without a declared default has none, while a declared default and a primitive `boolean` keep theirs. Without the helper the three tests fail (`expected: <false> but was: <true>`); with it they pass, and so do the 150 tests of `camel-package-maven-plugin`. ## Related findings that this pull request does not change - salesforce: the javadoc of `notifyForOperation*` and `includeDetails`, and the table in `salesforce-streaming.adoc`, say "defaults to false", but Camel does not send these values when they are not set. - salesforce: `pkChunking`, `pkChunkingChunkSize`, `pkChunkingParent` and `pkChunkingStartRow` never reach the bulk processor, because `SalesforceEndpointConfig.toValueMap()` has no entry for them; only the headers work. - jetty: the description of `useContinuation` does not mention the fallback to the component option. - fhir: `read.throwError=false` behaves like `true` (`FhirRead.java:251`). - Some declared `false` defaults are simplifications: jms `explicitQosEnabled` (null becomes `true` once a QoS option is set), file `idempotent` (null and `false` differ for `noop`), cxf `schemaValidationEnabled` (null leaves validation to CXF). - milo-server `enableAnonymousAuthentication` has a primitive setter, so it keeps `false`, although null falls back to a system property. - A header with `javaType = "Boolean"` and a declared default writes it as a string; no header lacks a declared default today. - The route attributes `streamCache`, `trace` and `messageHistory` show `false`, although null means the setting of the CamelContext (models are out of scope here). # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for the change (usually before you start working on it). # Apache Camel coding standards and style - [x] I checked that each commit in the pull request has a meaningful subject line and body. - [x] I have run `mvn clean install -Dquickly -DskipTests` from the root folder and then `mvn install -DskipTests -nsu` in the modules with a hand-written change and in `dsl/camel-endpointdsl` and `dsl/camel-componentdsl`, which generate their files only without `-Dquickly`, and I have committed all auto-generated changes. The commands that were run: ``` mvn test -nsu -B -pl tooling/maven/camel-package-maven-plugin -Dtest='EndpointSchemaGeneratorMojoTest#testBoolean*' -Dsurefire.failIfNoSpecifiedTests=false mvn test -nsu -B -pl tooling/maven/camel-package-maven-plugin mvn clean install -Dquickly -DskipTests mvn install -DskipTests -nsu -pl tooling/maven/camel-package-maven-plugin,components/camel-servicenow/camel-servicenow-component,components/camel-azure/camel-azure-storage-datalake,components/camel-salesforce/camel-salesforce-component,components/camel-undertow,components/camel-vertx/camel-vertx,components/camel-ai/camel-ai-tool,dsl/camel-endpointdsl,dsl/camel-componentdsl ``` The first command ran before and after the helper was added. # AI-assisted contributions - [x] If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR description identifies the AI tool used. The change, the tests, the classification of the options and this text were drafted with Claude Code (Anthropic). Each option was classified from the code that reads it, and each classification was checked by a second, independent AI review. _Claude Code on behalf of saravanakumar1987_ 🤖 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]
