This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch ih
in repository https://gitbox.apache.org/repos/asf/camel.git

commit ea60dfbd7efb488b242e06206d18d54e1f2a866f
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Nov 20 10:38:13 2025 +0100

    CAMEL-22693: Mark up EIP and endpoint headers that are of importance to 
make tooling, trouble shooting and development easier.
---
 catalog/camel-catalog/pom.xml                      |   2 +
 .../org/apache/camel/catalog/components/file.json  |   2 +-
 .../camel/catalog/main/important-headers.json      |   5 +
 .../org/apache/camel/catalog/models/aggregate.json |   2 +-
 .../org/apache/camel/catalog/models/split.json     |   2 +-
 .../org/apache/camel/component/file/file.json      |   2 +-
 .../apache/camel/component/file/FileConstants.java |   3 +-
 .../java/org/apache/camel/spi/Metadata.java        |   6 +
 .../src/main/java/org/apache/camel/Exchange.java   |  11 +-
 .../META-INF/org/apache/camel/model/aggregate.json |   2 +-
 .../META-INF/org/apache/camel/model/split.json     |   2 +-
 .../org/apache/camel/support/MessageHelper.java    |  10 +-
 .../apache/camel/util/ImportantHeaderUtils.java    |  56 +++++++
 .../camel/tooling/model/BaseOptionModel.java       |   9 +
 .../org/apache/camel/tooling/model/JsonMapper.java |   5 +
 .../packaging/EndpointSchemaGeneratorMojo.java     |   9 +-
 .../camel/maven/packaging/SchemaGeneratorMojo.java | 108 ++++++------
 .../packaging/UpdateHeaderImportantHelper.java     | 185 +++++++++++++++++++++
 .../main/java/org/apache/camel/spi/Metadata.java   |   6 +
 19 files changed, 366 insertions(+), 61 deletions(-)

diff --git a/catalog/camel-catalog/pom.xml b/catalog/camel-catalog/pom.xml
index d10d30ce8ef5..07c0221c5f75 100644
--- a/catalog/camel-catalog/pom.xml
+++ b/catalog/camel-catalog/pom.xml
@@ -159,6 +159,8 @@
                             <goal>update-sensitive-helper</goal>
                             <!-- update mime-types in camel-util -->
                             <goal>update-mime-type-helper</goal>
+                            <!-- update important headers in camel-util -->
+                            <goal>update-important-header-helper</goal>
                             <!-- update names in camel-main -->
                             <goal>update-main-helper</goal>
                             <!-- update test-infra metadata -->
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/file.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/file.json
index 5c1806a24571..6a455a342190 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/file.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/file.json
@@ -35,7 +35,7 @@
     "CamelFileLastModified": { "index": 1, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"long", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "A Long value containing the last modified 
timestamp of the file.", "constantName": 
"org.apache.camel.component.file.FileConstants#FILE_LAST_MODIFIED" },
     "CamelFileLocalWorkPath": { "index": 2, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"File", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The local work path", "constantName": 
"org.apache.camel.component.file.FileConstants#FILE_LOCAL_WORK_PATH" },
     "CamelFileNameOnly": { "index": 3, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Only the file name (the name with no leading 
paths).", "constantName": 
"org.apache.camel.component.file.FileConstants#FILE_NAME_ONLY" },
-    "CamelFileName": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "(producer) Specifies the name of the file to write 
(relative to the endpoint directory). This name can be a String; a String with 
a file or simple Language expression; or an Expression object. If it's null 
then Camel will auto-generate a filename bas [...]
+    "CamelFileName": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "important": true, "description": "(producer) Specifies the name of the 
file to write (relative to the endpoint directory). This name can be a String; 
a String with a file or simple Language expression; or an Expression object. If 
it's null then Camel will auto-gene [...]
     "CamelFileNameConsumed": { "index": 5, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The name of the file that has been consumed", 
"constantName": 
"org.apache.camel.component.file.FileConstants#FILE_NAME_CONSUMED" },
     "CamelFileAbsolute": { "index": 6, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "A boolean option specifying whether the 
consumed file denotes an absolute path or not. Should normally be false for 
relative paths. Absolute paths should normally not be used but we added to the 
move option to allow moving files to abs [...]
     "CamelFileAbsolutePath": { "index": 7, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The absolute path to the file. For relative 
files this path holds the relative path instead.", "constantName": 
"org.apache.camel.component.file.FileConstants#FILE_ABSOLUTE_PATH" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/important-headers.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/important-headers.json
new file mode 100644
index 000000000000..c5b0e2b95375
--- /dev/null
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/important-headers.json
@@ -0,0 +1,5 @@
+[
+  "CamelAggregatedSize",
+  "CamelFileName",
+  "CamelSplitSize"
+]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/aggregate.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/aggregate.json
index 2aba013108c2..e4ff73c425d2 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/aggregate.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/aggregate.json
@@ -46,7 +46,7 @@
     "outputs": { "index": 31, "kind": "element", "displayName": "Outputs", 
"group": "common", "required": true, "type": "array", "javaType": 
"java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", 
"claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", 
"doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", 
"idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", 
"kamelet", "loadBalance", "log", "loop", "ma [...]
   },
   "exchangeProperties": {
-    "CamelAggregatedSize": { "index": 0, "kind": "exchangeProperty", 
"displayName": "Aggregated Size", "label": "producer", "required": false, 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"description": "Number of exchanges that was grouped together." },
+    "CamelAggregatedSize": { "index": 0, "kind": "exchangeProperty", 
"displayName": "Aggregated Size", "label": "producer", "required": false, 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"important": true, "description": "Number of exchanges that was grouped 
together." },
     "CamelAggregatedTimeout": { "index": 1, "kind": "exchangeProperty", 
"displayName": "Aggregated Timeout", "label": "producer", "required": false, 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"description": "The time in millis this group will timeout" },
     "CamelAggregatedCompletedBy": { "index": 2, "kind": "exchangeProperty", 
"displayName": "Aggregated Completed By", "label": "producer", "required": 
false, "javaType": "String", "deprecated": false, "autowired": false, "secret": 
false, "description": "Enum that tell how this group was completed" },
     "CamelAggregatedCorrelationKey": { "index": 3, "kind": "exchangeProperty", 
"displayName": "Aggregated Correlation Key", "label": "producer", "required": 
false, "javaType": "String", "deprecated": false, "autowired": false, "secret": 
false, "description": "The correlation key for this aggregation group" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/split.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/split.json
index b7f0032927af..198495663989 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/split.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/split.json
@@ -35,6 +35,6 @@
   "exchangeProperties": {
     "CamelSplitIndex": { "index": 0, "kind": "exchangeProperty", 
"displayName": "Split Index", "label": "producer", "required": false, 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"description": "A split counter that increases for each Exchange being split. 
The counter starts from 0." },
     "CamelSplitComplete": { "index": 1, "kind": "exchangeProperty", 
"displayName": "Split Complete", "label": "producer", "required": false, 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "description": "Whether this Exchange is the last." },
-    "CamelSplitSize": { "index": 2, "kind": "exchangeProperty", "displayName": 
"Split Size", "label": "producer", "required": false, "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
total number of Exchanges that was split. This property is not applied for 
stream based splitting, except for the very last message because then Camel 
knows the total size." }
+    "CamelSplitSize": { "index": 2, "kind": "exchangeProperty", "displayName": 
"Split Size", "label": "producer", "required": false, "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "important": true, 
"description": "The total number of Exchanges that was split. This property is 
not applied for stream based splitting, except for the very last message 
because then Camel knows the total size." }
   }
 }
diff --git 
a/components/camel-file/src/generated/resources/META-INF/org/apache/camel/component/file/file.json
 
b/components/camel-file/src/generated/resources/META-INF/org/apache/camel/component/file/file.json
index 5c1806a24571..6a455a342190 100644
--- 
a/components/camel-file/src/generated/resources/META-INF/org/apache/camel/component/file/file.json
+++ 
b/components/camel-file/src/generated/resources/META-INF/org/apache/camel/component/file/file.json
@@ -35,7 +35,7 @@
     "CamelFileLastModified": { "index": 1, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"long", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "A Long value containing the last modified 
timestamp of the file.", "constantName": 
"org.apache.camel.component.file.FileConstants#FILE_LAST_MODIFIED" },
     "CamelFileLocalWorkPath": { "index": 2, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"File", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The local work path", "constantName": 
"org.apache.camel.component.file.FileConstants#FILE_LOCAL_WORK_PATH" },
     "CamelFileNameOnly": { "index": 3, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Only the file name (the name with no leading 
paths).", "constantName": 
"org.apache.camel.component.file.FileConstants#FILE_NAME_ONLY" },
-    "CamelFileName": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "(producer) Specifies the name of the file to write 
(relative to the endpoint directory). This name can be a String; a String with 
a file or simple Language expression; or an Expression object. If it's null 
then Camel will auto-generate a filename bas [...]
+    "CamelFileName": { "index": 4, "kind": "header", "displayName": "", 
"group": "common", "label": "", "required": false, "javaType": "String", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "important": true, "description": "(producer) Specifies the name of the 
file to write (relative to the endpoint directory). This name can be a String; 
a String with a file or simple Language expression; or an Expression object. If 
it's null then Camel will auto-gene [...]
     "CamelFileNameConsumed": { "index": 5, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The name of the file that has been consumed", 
"constantName": 
"org.apache.camel.component.file.FileConstants#FILE_NAME_CONSUMED" },
     "CamelFileAbsolute": { "index": 6, "kind": "header", "displayName": "", 
"group": "consumer", "label": "consumer", "required": false, "javaType": 
"Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "A boolean option specifying whether the 
consumed file denotes an absolute path or not. Should normally be false for 
relative paths. Absolute paths should normally not be used but we added to the 
move option to allow moving files to abs [...]
     "CamelFileAbsolutePath": { "index": 7, "kind": "header", "displayName": 
"", "group": "consumer", "label": "consumer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The absolute path to the file. For relative 
files this path holds the relative path instead.", "constantName": 
"org.apache.camel.component.file.FileConstants#FILE_ABSOLUTE_PATH" },
diff --git 
a/components/camel-file/src/main/java/org/apache/camel/component/file/FileConstants.java
 
b/components/camel-file/src/main/java/org/apache/camel/component/file/FileConstants.java
index f40236901874..027fd8a5e59a 100644
--- 
a/components/camel-file/src/main/java/org/apache/camel/component/file/FileConstants.java
+++ 
b/components/camel-file/src/main/java/org/apache/camel/component/file/FileConstants.java
@@ -36,7 +36,8 @@ public final class FileConstants {
                             + " `null` then Camel will auto-generate a 
filename based on the message"
                             + " unique ID. (consumer) Name of the consumed 
file as a relative file path with offset from the"
                             + " starting directory configured on the 
endpoint.",
-              javaType = "String")
+              javaType = "String",
+              important = true)
     public static final String FILE_NAME = Exchange.FILE_NAME;
     @Metadata(label = "consumer", description = "The name of the file that has 
been consumed", javaType = "String")
     public static final String FILE_NAME_CONSUMED = 
Exchange.FILE_NAME_CONSUMED;
diff --git 
a/core/camel-api/src/generated/java/org/apache/camel/spi/Metadata.java 
b/core/camel-api/src/generated/java/org/apache/camel/spi/Metadata.java
index 462df3cc4dca..c396d77fd2da 100644
--- a/core/camel-api/src/generated/java/org/apache/camel/spi/Metadata.java
+++ b/core/camel-api/src/generated/java/org/apache/camel/spi/Metadata.java
@@ -175,4 +175,10 @@ public @interface Metadata {
      * Annotations data for Camel concepts such as components, EIP, etc.
      */
     String[] annotations() default {};
+
+    /**
+     * Whether this option is important
+     */
+    boolean important() default false;
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/Exchange.java 
b/core/camel-api/src/main/java/org/apache/camel/Exchange.java
index 884d2e35904b..68684368c130 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Exchange.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Exchange.java
@@ -70,7 +70,8 @@ public interface Exchange extends VariableAware {
     String AUTHENTICATION = "CamelAuthentication";
     String AUTHENTICATION_FAILURE_POLICY_ID = 
"CamelAuthenticationFailurePolicyId";
 
-    @Metadata(label = "aggregate", description = "Number of exchanges that was 
grouped together.", javaType = "int")
+    @Metadata(label = "aggregate", description = "Number of exchanges that was 
grouped together.", javaType = "int",
+              important = true)
     String AGGREGATED_SIZE = "CamelAggregatedSize";
     @Metadata(label = "aggregate", description = "The time in millis this 
group will timeout", javaType = "long")
     String AGGREGATED_TIMEOUT = "CamelAggregatedTimeout";
@@ -112,6 +113,7 @@ public interface Exchange extends VariableAware {
     String CLAIM_CHECK_REPOSITORY = "CamelClaimCheckRepository";
     String CONTENT_ENCODING = "Content-Encoding";
     String CONTENT_LENGTH = "Content-Length";
+    @Metadata(important = true)
     String CONTENT_TYPE = "Content-Type";
     String COOKIE_HANDLER = "CamelCookieHandler";
     String CORRELATION_ID = "CamelCorrelationId";
@@ -130,7 +132,6 @@ public interface Exchange extends VariableAware {
               description = "Whether this exchange is a duplicate detected by 
the Idempotent Consumer EIP",
               javaType = "boolean")
     String DUPLICATE_MESSAGE = "CamelDuplicateMessage";
-
     String DOCUMENT_BUILDER_FACTORY = "CamelDocumentBuilderFactory";
 
     @Metadata(label = "doCatch,doFinally,errorHandler,onException",
@@ -154,6 +155,7 @@ public interface Exchange extends VariableAware {
     String FATAL_FALLBACK_ERROR_HANDLER = "CamelFatalFallbackErrorHandler";
     String FILE_CONTENT_TYPE = "CamelFileContentType";
     String FILE_LOCAL_WORK_PATH = "CamelFileLocalWorkPath";
+    @Metadata(important = true)
     String FILE_NAME = "CamelFileName";
     String FILE_NAME_ONLY = "CamelFileNameOnly";
     String FILE_NAME_PRODUCED = "CamelFileNameProduced";
@@ -182,6 +184,7 @@ public interface Exchange extends VariableAware {
     String HTTP_PROTOCOL_VERSION = "CamelHttpProtocolVersion";
     String HTTP_QUERY = "CamelHttpQuery";
     String HTTP_RAW_QUERY = "CamelHttpRawQuery";
+    @Metadata(important = true)
     String HTTP_RESPONSE_CODE = "CamelHttpResponseCode";
     String HTTP_RESPONSE_TEXT = "CamelHttpResponseText";
     String HTTP_URI = "CamelHttpUri";
@@ -277,11 +280,13 @@ public interface Exchange extends VariableAware {
     String SPLIT_COMPLETE = "CamelSplitComplete";
     @Metadata(label = "split",
               description = "The total number of Exchanges that was split. 
This property is not applied for stream based splitting, except for the very 
last message because then Camel knows the total size.",
-              javaType = "int")
+              javaType = "int",
+              important = true)
     String SPLIT_SIZE = "CamelSplitSize";
     @Metadata(label = "step", description = "The id of the Step EIP", javaType 
= "String")
     String STEP_ID = "CamelStepId";
 
+    @Metadata(important = true)
     String TIMER_COUNTER = "CamelTimerCounter";
     String TIMER_FIRED_TIME = "CamelTimerFiredTime";
     String TIMER_NAME = "CamelTimerName";
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/aggregate.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/aggregate.json
index 2aba013108c2..e4ff73c425d2 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/aggregate.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/aggregate.json
@@ -46,7 +46,7 @@
     "outputs": { "index": 31, "kind": "element", "displayName": "Outputs", 
"group": "common", "required": true, "type": "array", "javaType": 
"java.util.List", "oneOf": [ "aggregate", "bean", "choice", "circuitBreaker", 
"claimCheck", "convertBodyTo", "convertHeaderTo", "convertVariableTo", "delay", 
"doCatch", "doFinally", "doTry", "dynamicRouter", "enrich", "filter", 
"idempotentConsumer", "intercept", "interceptFrom", "interceptSendToEndpoint", 
"kamelet", "loadBalance", "log", "loop", "ma [...]
   },
   "exchangeProperties": {
-    "CamelAggregatedSize": { "index": 0, "kind": "exchangeProperty", 
"displayName": "Aggregated Size", "label": "producer", "required": false, 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"description": "Number of exchanges that was grouped together." },
+    "CamelAggregatedSize": { "index": 0, "kind": "exchangeProperty", 
"displayName": "Aggregated Size", "label": "producer", "required": false, 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"important": true, "description": "Number of exchanges that was grouped 
together." },
     "CamelAggregatedTimeout": { "index": 1, "kind": "exchangeProperty", 
"displayName": "Aggregated Timeout", "label": "producer", "required": false, 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"description": "The time in millis this group will timeout" },
     "CamelAggregatedCompletedBy": { "index": 2, "kind": "exchangeProperty", 
"displayName": "Aggregated Completed By", "label": "producer", "required": 
false, "javaType": "String", "deprecated": false, "autowired": false, "secret": 
false, "description": "Enum that tell how this group was completed" },
     "CamelAggregatedCorrelationKey": { "index": 3, "kind": "exchangeProperty", 
"displayName": "Aggregated Correlation Key", "label": "producer", "required": 
false, "javaType": "String", "deprecated": false, "autowired": false, "secret": 
false, "description": "The correlation key for this aggregation group" },
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/split.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/split.json
index b7f0032927af..198495663989 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/split.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/split.json
@@ -35,6 +35,6 @@
   "exchangeProperties": {
     "CamelSplitIndex": { "index": 0, "kind": "exchangeProperty", 
"displayName": "Split Index", "label": "producer", "required": false, 
"javaType": "int", "deprecated": false, "autowired": false, "secret": false, 
"description": "A split counter that increases for each Exchange being split. 
The counter starts from 0." },
     "CamelSplitComplete": { "index": 1, "kind": "exchangeProperty", 
"displayName": "Split Complete", "label": "producer", "required": false, 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "description": "Whether this Exchange is the last." },
-    "CamelSplitSize": { "index": 2, "kind": "exchangeProperty", "displayName": 
"Split Size", "label": "producer", "required": false, "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
total number of Exchanges that was split. This property is not applied for 
stream based splitting, except for the very last message because then Camel 
knows the total size." }
+    "CamelSplitSize": { "index": 2, "kind": "exchangeProperty", "displayName": 
"Split Size", "label": "producer", "required": false, "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "important": true, 
"description": "The total number of Exchanges that was split. This property is 
not applied for stream based splitting, except for the very last message 
because then Camel knows the total size." }
   }
 }
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java 
b/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java
index c0987d91feb3..bcbe22c5313f 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java
@@ -40,6 +40,7 @@ import org.apache.camel.spi.DataTypeAware;
 import org.apache.camel.spi.ExchangeFormatter;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.camel.trait.message.MessageTrait;
+import org.apache.camel.util.ImportantHeaderUtils;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.URISupport;
@@ -1009,6 +1010,9 @@ public final class MessageHelper {
                 if (type != null) {
                     jh.put("type", type);
                 }
+                if (ImportantHeaderUtils.isImportantHeader(key)) {
+                    jh.put("important", true);
+                }
                 if (value != null) {
                     Object s = Jsoner.trySerialize(value);
                     if (s == null) {
@@ -1039,10 +1043,14 @@ public final class MessageHelper {
                 Object value = entry.getValue();
                 String type = ObjectHelper.classCanonicalName(value);
                 JsonObject jh = new JsonObject();
-                jh.put("key", entry.getKey());
+                String key = entry.getKey();
+                jh.put("key", key);
                 if (type != null) {
                     jh.put("type", type);
                 }
+                if (ImportantHeaderUtils.isImportantHeader(key)) {
+                    jh.put("important", true);
+                }
                 // dump header value as JSon, use Camel type converter to 
convert to String
                 if (value != null) {
                     Object s = Jsoner.trySerialize(value);
diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/ImportantHeaderUtils.java 
b/core/camel-util/src/main/java/org/apache/camel/util/ImportantHeaderUtils.java
new file mode 100644
index 000000000000..1861151acf70
--- /dev/null
+++ 
b/core/camel-util/src/main/java/org/apache/camel/util/ImportantHeaderUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.util;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public final class ImportantHeaderUtils {
+
+    private static final Set<String> IMPORTANT_HEADER_KEYS = 
Collections.unmodifiableSet(new HashSet<>(
+            Arrays.asList(
+                    // Generated by camel build tools - do NOT edit this list!
+                    // IMPORTANT-HEADER-KEYS: START
+                    "CamelAggregatedSize",
+                    "CamelFileName",
+                    "CamelSplitSize"
+            // IMPORTANT-HEADER-KEYS: END
+            )));
+
+    private ImportantHeaderUtils() {
+    }
+
+    /**
+     * All the important header keys (unmodifiable)
+     */
+    public static Set<String> getImportantHeaderKeys() {
+        return IMPORTANT_HEADER_KEYS;
+    }
+
+    /**
+     * Whether the given header or exchange properties is marked as important.
+     *
+     * @param  key the header key
+     * @return     true if important, false otherwise
+     */
+    public static boolean isImportantHeader(String key) {
+        return IMPORTANT_HEADER_KEYS.contains(key);
+    }
+
+}
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseOptionModel.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseOptionModel.java
index 71357d233ef6..29d013d415dc 100644
--- 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseOptionModel.java
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/BaseOptionModel.java
@@ -51,6 +51,7 @@ public abstract class BaseOptionModel {
     protected boolean supportFileReference;
     protected boolean largeInput;
     protected String inputLanguage;
+    protected boolean important;
 
     // todo: move this as a helper method
     protected boolean newGroup; // special for documentation rendering
@@ -303,6 +304,14 @@ public abstract class BaseOptionModel {
         this.inputLanguage = inputLanguage;
     }
 
+    public boolean isImportant() {
+        return important;
+    }
+
+    public void setImportant(boolean important) {
+        this.important = important;
+    }
+
     public String getShortGroup() {
         if (group != null && group.endsWith(" (advanced)")) {
             return group.substring(0, group.length() - 11);
diff --git 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
index 8256bc9caa83..eed5132c919c 100644
--- 
a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
+++ 
b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/JsonMapper.java
@@ -598,6 +598,7 @@ public final class JsonMapper {
         
option.setSupportFileReference(mp.getBooleanOrDefault("supportFileReference", 
false));
         option.setLargeInput(mp.getBooleanOrDefault("largeInput", false));
         option.setInputLanguage(mp.getString("inputLanguage"));
+        option.setImportant(mp.getBooleanOrDefault("important", false));
     }
 
     private static void parseGroup(JsonObject mp, MainGroupModel option) {
@@ -733,6 +734,10 @@ public final class JsonMapper {
             // only include if supported to not regen all files
             prop.put("inputLanguage", option.getInputLanguage());
         }
+        if (option.isImportant()) {
+            // only include if supported to not regen all files
+            prop.put("important", option.isImportant());
+        }
         prop.put("asPredicate", option.isAsPredicate());
         prop.put("configurationClass", option.getConfigurationClass());
         prop.put("configurationField", option.getConfigurationField());
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
index ea8b56bd145c..02fc1ba522c2 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
@@ -403,7 +403,6 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
     private boolean addEndpointHeader(ComponentModel componentModel, String 
scheme, Field field, String headersNameProvider) {
         final Metadata metadata = field.getAnnotation(Metadata.class);
         if (metadata == null) {
-
             if (getLog().isDebugEnabled()) {
                 getLog().debug(String.format("The field %s in class %s has no 
Metadata", field.getName(),
                         field.getDeclaringClass().getName()));
@@ -412,7 +411,6 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         }
         final String[] applicableFor = metadata.applicableFor();
         if (applicableFor.length > 0 && 
Arrays.stream(applicableFor).noneMatch(s -> s.equals(scheme))) {
-
             if (getLog().isDebugEnabled()) {
                 getLog().debug(String.format("The field %s in class %s is not 
applicable for %s", field.getName(),
                         field.getDeclaringClass().getName(), scheme));
@@ -436,6 +434,7 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         header.setGroup(EndpointHelper.labelAsGroupName(metadata.label(), 
componentModel.isConsumerOnly(),
                 componentModel.isProducerOnly()));
         header.setLabel(metadata.label());
+        header.setImportant(metadata.important());
         try {
             header.setEnums(getEnums(metadata, header.getJavaType().isEmpty() 
? null : loadClass(header.getJavaType())));
         } catch (NoClassDefFoundError e) {
@@ -1000,6 +999,7 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
                 boolean supportFileReference = metadata != null && 
metadata.supportFileReference();
                 boolean largeInput = metadata != null && metadata.largeInput();
                 String inputLanguage = metadata != null ? 
metadata.inputLanguage() : null;
+                boolean important = metadata != null && metadata.important();
 
                 // we do not yet have default values / notes / as no annotation
                 // support yet
@@ -1118,6 +1118,7 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
                     option.setSupportFileReference(supportFileReference);
                     option.setLargeInput(largeInput);
                     option.setInputLanguage(inputLanguage);
+                    option.setImportant(important);
                     componentModel.addComponentOption(option);
                 }
             }
@@ -1375,6 +1376,7 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         boolean isSecret = secret != null && secret || param.secret();
         boolean isAutowired = metadata != null && metadata.autowired();
         boolean supportFileReference = metadata != null && 
metadata.supportFileReference();
+        boolean important = metadata != null && metadata.important();
         String group = EndpointHelper.labelAsGroupName(label, 
componentModel.isConsumerOnly(),
                 componentModel.isProducerOnly());
 
@@ -1431,6 +1433,7 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         option.setOptionalPrefix(paramOptionalPrefix);
         option.setMultiValue(multiValue);
         option.setSupportFileReference(supportFileReference);
+        option.setImportant(important);
         if (componentOption) {
             option.setKind("property");
             componentModel.addComponentOption((ComponentOptionModel) option);
@@ -1564,6 +1567,7 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             boolean isAutowired = metadata != null && metadata.autowired();
             boolean supportFileReference = metadata != null && 
metadata.supportFileReference();
             boolean largeInput = metadata != null && metadata.largeInput();
+            boolean important = metadata != null && metadata.important();
             String inputLanguage = metadata != null ? metadata.inputLanguage() 
: null;
             String group = EndpointHelper.labelAsGroupName(label, 
componentModel.isConsumerOnly(),
                     componentModel.isProducerOnly());
@@ -1619,6 +1623,7 @@ public class EndpointSchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             option.setSupportFileReference(supportFileReference);
             option.setLargeInput(largeInput);
             option.setInputLanguage(inputLanguage);
+            option.setImportant(important);
             if (componentModel.getEndpointOptions().stream().noneMatch(opt -> 
name.equals(opt.getName()))) {
                 componentModel.addEndpointOption((EndpointOptionModel) option);
             }
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
index 969e8263a1db..a06a20503ae4 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
@@ -368,6 +368,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
                         String valueName = "Camel" + 
Character.toUpperCase(n2.charAt(0)) + n2.substring(1);
                         o.setName(valueName);
                         o.setDescription(metadata.description());
+                        o.setImportant(metadata.important());
                         if (!metadata.displayName().isEmpty()) {
                             o.setDisplayName(metadata.displayName());
                         } else {
@@ -550,9 +551,11 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             }
         }
 
+        boolean important = false;
         String displayName = null;
         if (metadata != null) {
             displayName = metadata.displayName();
+            important = metadata.important();
         }
         boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != 
null;
         String deprecationNote = null;
@@ -566,7 +569,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
 
         EipOptionModel ep = createOption(name, displayName, "attribute", 
fieldTypeName,
                 required, defaultValue, label, docComment, deprecated, 
deprecationNote, isEnum, enums,
-                null, false, isDuration);
+                null, false, isDuration, important);
         eipOptions.add(ep);
 
         return false;
@@ -606,8 +609,10 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             }
         }
 
+        boolean important = false;
         if (metadata != null) {
             displayName = metadata.displayName();
+            important = metadata.important();
         }
         boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != 
null;
         String deprecationNote = null;
@@ -621,7 +626,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
 
         EipOptionModel ep = createOption(name, displayName, "value", 
fieldTypeName, required,
                 defaultValue, label, docComment, deprecated, deprecationNote, 
false, null,
-                null, false, isDuration);
+                null, false, isDuration, important);
         eipOptions.add(ep);
     }
 
@@ -691,9 +696,11 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
                 oneOfTypes.add("otherwise");
             }
 
+            boolean important = false;
             String displayName = null;
             if (metadata != null) {
                 displayName = metadata.displayName();
+                important = metadata.important();
             }
             boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
@@ -707,7 +714,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
 
             EipOptionModel ep = createOption(name, displayName, kind, 
fieldTypeName, required, defaultValue, label,
                     docComment, deprecated, deprecationNote, isEnum, enums,
-                    oneOfTypes, asPredicate, isDuration);
+                    oneOfTypes, asPredicate, isDuration, important);
             eipOptions.add(ep);
         }
     }
@@ -735,10 +742,12 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
                 oneOfTypes.add(child);
             }
 
+            boolean important = false;
             String displayName = null;
             Metadata metadata = fieldElement.getAnnotation(Metadata.class);
             if (metadata != null) {
                 displayName = metadata.displayName();
+                important = metadata.important();
             }
             boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
@@ -753,7 +762,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             final String kind = "element";
             EipOptionModel ep = createOption(name, displayName, kind, 
fieldTypeName, required, defaultValue, label, docComment,
                     deprecated, deprecationNote, false, null, oneOfTypes,
-                    false, false);
+                    false, false, important);
             eipOptions.add(ep);
         }
     }
@@ -763,13 +772,13 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         EipOptionModel ep = createOption("doCatch", "Do Catch", "element",
                 "java.util.List<org.apache.camel.model.CatchDefinition>", 
false, "",
                 "", "Catches exceptions as part of a try, catch, finally 
block", false,
-                null, false, null, Set.of("doCatch"), false, false);
+                null, false, null, Set.of("doCatch"), false, false, false);
         eipOptions.add(ep);
 
         ep = createOption("doFinally", "Do Finally", "element", 
"org.apache.camel.model.FinallyDefinition", false,
                 "",
                 "", "Path traversed when a try, catch, finally block exits", 
false,
-                null, false, null, null, false, false);
+                null, false, null, null, false, false, false);
         eipOptions.add(ep);
     }
 
@@ -779,82 +788,75 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         String docComment = findJavaDoc(null, "group", null, classElement, 
true);
         EipOptionModel ep
                 = createOption("group", "Group", "attribute", 
"java.lang.String", false, "", "", docComment, false, null,
-                        false, null, null, false, false);
+                        false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // nodePrefixId
         docComment = findJavaDoc(null, "nodePrefixId", null, classElement, 
true);
         ep = createOption("nodePrefixId", "Node Prefix Id", "attribute", 
"java.lang.String", false, "", "", docComment, false,
                 null,
-                false, null, null, false, false);
+                false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // routeConfigurationId
         docComment = findJavaDoc(null, "routeConfigurationId", null, 
classElement, true);
         ep = createOption("routeConfigurationId", "Route Configuration Id", 
"attribute", "java.lang.String", false, "", "",
                 docComment, false, null,
-                false, null, null, false, false);
+                false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // autoStartup
         docComment = findJavaDoc(null, "autoStartup", null, classElement, 
true);
         ep = createOption("autoStartup", "Auto Startup", "attribute", 
"java.lang.Boolean", false, "true", "", docComment, false,
-                null, false, null, null, false, false);
+                null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // startupOrder
         docComment = findJavaDoc(null, "startupOrder", null, classElement, 
true);
         ep = createOption("startupOrder", "Startup Order", "attribute", 
"java.lang.Integer", false, "", "advanced", docComment,
-                false,
-                null,
-                false, null, null, false, false);
+                false, null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // stream cache
         docComment = findJavaDoc(null, "streamCache", null, classElement, 
true);
         ep = createOption("streamCache", "Stream Cache", "attribute", 
"java.lang.Boolean", false, "", "", docComment, false,
-                null,
-                false, null, null, false, false);
+                null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // trace
         docComment = findJavaDoc(null, "trace", null, classElement, true);
         ep = createOption("trace", "Trace", "attribute", "java.lang.Boolean", 
false, "", "", docComment, false, null, false,
-                null,
-                null, false, false);
+                null, null, false, false, false);
         eipOptions.add(ep);
 
         // message history
         docComment = findJavaDoc(null, "messageHistory", null, classElement, 
true);
         ep = createOption("messageHistory", "Message History", "attribute", 
"java.lang.Boolean", false, "", "", docComment,
-                false, null, false, null, null, false, false);
+                false, null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // log mask
         docComment = findJavaDoc(null, "logMask", null, classElement, true);
         ep = createOption("logMask", "Log Mask", "attribute", 
"java.lang.Boolean", false, "false", "", docComment, false, null,
-                false, null, null, false, false);
+                false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // delayer
         docComment = findJavaDoc(null, "delayer", null, classElement, true);
         ep = createOption("delayer", "Delayer", "attribute", "java.lang.Long", 
false, "advanced", "", docComment, false, null,
-                false,
-                null, null, false, true);
+                false, null, null, false, true, false);
         eipOptions.add(ep);
 
         // errorHandlerRef
         docComment = findJavaDoc(null, "errorHandlerRef", null, classElement, 
true);
         ep = createOption("errorHandlerRef", "Error Handler", "attribute", 
"java.lang.String", false, "", "error", docComment,
-                false,
-                null, false, null, null, false, false);
+                false, null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // routePolicyRef
         docComment = findJavaDoc(null, "routePolicyRef", null, classElement, 
true);
         ep = createOption("routePolicyRef", "Route Policy", "attribute", 
"java.lang.String", false, "", "", docComment, false,
-                null,
-                false, null, null, false, false);
+                null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // shutdownRoute
@@ -863,8 +865,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         enums.add("Defer");
         docComment = findJavaDoc(null, "shutdownRoute", "Default", 
classElement, true);
         ep = createOption("shutdownRoute", "Shutdown Route", "attribute", 
"org.apache.camel.ShutdownRoute", false, "",
-                "advanced",
-                docComment, false, null, true, enums, null, false, false);
+                "advanced", docComment, false, null, true, enums, null, false, 
false, false);
         eipOptions.add(ep);
 
         // shutdownRunningTask
@@ -874,36 +875,34 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         docComment = findJavaDoc(null, "shutdownRunningTask", 
"CompleteCurrentTaskOnly", classElement, true);
         ep = createOption("shutdownRunningTask", "Shutdown Running Task", 
"attribute", "org.apache.camel.ShutdownRunningTask",
                 false, "", "advanced", docComment, false, null, true, enums,
-                null, false, false);
+                null, false, false, false);
         eipOptions.add(ep);
 
         // precondition
         docComment = findJavaDoc(null, "precondition", null, classElement, 
true);
         ep = createOption("precondition", "Precondition", "attribute", 
"java.lang.String", false, "", "advanced", docComment,
-                false,
-                null, false, null, null, false, false);
+                false, null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // error handler
         docComment = findJavaDoc(null, "errorHandler", null, classElement, 
true);
         ep = createOption("errorHandler", "Error Handler", "element", 
"org.apache.camel.model.ErrorHandlerDefinition", false,
                 "",
-                "error", docComment, false,
-                null, false, null, null, false, false);
+                "error", docComment, false, null, false, null, null, false, 
false, false);
         eipOptions.add(ep);
 
         // input type
         docComment = findJavaDoc(null, "inputType", null, classElement, true);
         ep = createOption("inputType", "Input Type", "element", 
"org.apache.camel.model.InputTypeDefinition", false, "",
                 "advanced", docComment, false,
-                null, false, null, null, false, false);
+                null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // output type
         docComment = findJavaDoc(null, "outputType", null, classElement, true);
         ep = createOption("outputType", "Output Type", "element", 
"org.apache.camel.model.OutputTypeDefinition", false, "",
                 "advanced", docComment, false,
-                null, false, null, null, false, false);
+                null, false, null, null, false, false, false);
         eipOptions.add(ep);
 
         // input
@@ -911,7 +910,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         oneOfTypes.add("from");
         docComment = findJavaDoc(null, "input", null, classElement, true);
         ep = createOption("input", "Input", "element", 
"org.apache.camel.model.FromDefinition", true, "", "", docComment, false,
-                null, false, null, oneOfTypes, false, false);
+                null, false, null, oneOfTypes, false, false, false);
         eipOptions.add(ep);
 
         // outputs
@@ -935,7 +934,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         docComment = findJavaDoc(null, "outputs", null, classElement, true);
         ep = createOption("outputs", "Outputs", "element", 
"java.util.List<org.apache.camel.model.ProcessorDefinition<?>>",
                 true, "", "", docComment, false, null, false, null,
-                oneOfTypes, false, false);
+                oneOfTypes, false, false, false);
         eipOptions.add(ep);
     }
 
@@ -947,21 +946,21 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         String docComment = findJavaDoc(null, "id", null, classElement, true);
         EipOptionModel ep
                 = createOption("id", "Id", "attribute", "java.lang.String", 
false, "", "", docComment, false, null, false,
-                        null, null, false, false);
+                        null, null, false, false, false);
         eipOptions.add(ep);
         // description
         docComment = findJavaDoc(null, "description", null, classElement, 
true);
         ep = createOption("description", "Description", "attribute", 
"java.lang.String", false, "",
                 "",
                 docComment, false, null, false, null, null,
-                false, false);
+                false, false, false);
         eipOptions.add(ep);
         // note
         docComment = findJavaDoc(null, "note", null, classElement, true);
         ep = createOption("note", "Note", "attribute", "java.lang.String", 
false, "",
                 "",
                 docComment, false, null, false, null, null,
-                false, false);
+                false, false, false);
         eipOptions.add(ep);
     }
 
@@ -982,7 +981,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             EipOptionModel ep = createOption("routes", "Routes", "element",
                     fieldTypeName, false, "", "", "Contains the Camel routes",
                     false, null, false, null, oneOfTypes,
-                    false, false);
+                    false, false, false);
             eipOptions.add(ep);
         }
     }
@@ -1003,7 +1002,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
 
             EipOptionModel ep = createOption("rests", "Rests", "element", 
fieldTypeName, false, "", "",
                     "Contains the rest services defined using the rest-dsl", 
false, null, false,
-                    null, oneOfTypes, false, false);
+                    null, oneOfTypes, false, false, false);
             eipOptions.add(ep);
         }
     }
@@ -1034,10 +1033,12 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             } else {
                 oneOfTypes = Set.of("setVariable");
             }
+            boolean important = false;
             String displayName = null;
             Metadata metadata = fieldElement.getAnnotation(Metadata.class);
             if (metadata != null) {
                 displayName = metadata.displayName();
+                important = metadata.important();
             }
             boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
@@ -1053,7 +1054,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             EipOptionModel ep
                     = createOption(name, displayName, kind, typeName, true, 
"", label,
                             "Contains the " + fieldName + " to be set", 
deprecated, deprecationNote,
-                            false, null, oneOfTypes, false, false);
+                            false, null, oneOfTypes, false, false, important);
             eipOptions.add(ep);
         }
     }
@@ -1084,8 +1085,10 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             if (metadata == null) {
                 metadata = methodElement != null ? 
methodElement.getAnnotation(Metadata.class) : null;
             }
+            boolean important = false;
             if (metadata != null) {
                 displayName = metadata.displayName();
+                important = metadata.important();
             }
             boolean deprecated = false;
             if (fieldElement != null && 
fieldElement.getAnnotation(Deprecated.class) != null
@@ -1104,7 +1107,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             String kind = "element";
             EipOptionModel ep
                     = createOption(name, displayName, kind, typeName, true, 
"", label, "", deprecated, deprecationNote,
-                            false, null, oneOfTypes, false, false);
+                            false, null, oneOfTypes, false, false, important);
             eipOptions.add(ep);
         }
     }
@@ -1124,10 +1127,12 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
 
             // gather oneOf which extends any of the output base classes
             Set<String> oneOfTypes = getOneOfs(ONE_OF_VERBS);
+            boolean important = false;
             String displayName = null;
             Metadata metadata = fieldElement.getAnnotation(Metadata.class);
             if (metadata != null) {
                 displayName = metadata.displayName();
+                important = metadata.important();
             }
             boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
@@ -1141,7 +1146,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
 
             String kind = "element";
             EipOptionModel ep = createOption(name, displayName, kind, 
fieldTypeName, true, "", label, docComment, deprecated,
-                    deprecationNote, false, null, oneOfTypes, false, false);
+                    deprecationNote, false, null, oneOfTypes, false, false, 
important);
             eipOptions.add(ep);
         }
 
@@ -1160,10 +1165,12 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             }
 
             String fieldTypeName = 
getTypeName(GenericsUtil.resolveType(originalClassType, fieldElement));
+            boolean important = false;
             String displayName = null;
             Metadata metadata = fieldElement.getAnnotation(Metadata.class);
             if (metadata != null) {
                 displayName = metadata.displayName();
+                important = metadata.important();
             }
             boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
@@ -1177,7 +1184,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
 
             String kind = "element";
             EipOptionModel ep = createOption(name, displayName, kind, 
fieldTypeName, false, "", label, docComment, deprecated,
-                    deprecationNote, false, null, null, false, false);
+                    deprecationNote, false, null, null, false, false, 
important);
             // insert before "to"
             eipOptions.add(ep);
         }
@@ -1213,10 +1220,12 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             // gather oneOf expression/predicates which uses language
             Set<String> oneOfTypes = getOneOfs(ONE_OF_LANGUAGES);
 
+            boolean important = false;
             String displayName = null;
             Metadata metadata = fieldElement.getAnnotation(Metadata.class);
             if (metadata != null) {
                 displayName = metadata.displayName();
+                important = metadata.important();
             }
             boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
@@ -1232,7 +1241,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             final boolean required = expressionRequired(name);
             EipOptionModel ep
                     = createOption(name, displayName, kind, fieldTypeName, 
required, "", label, docComment, deprecated,
-                            deprecationNote, false, null, oneOfTypes, 
asPredicate, false);
+                            deprecationNote, false, null, oneOfTypes, 
asPredicate, false, important);
             eipOptions.add(ep);
         }
     }
@@ -1275,10 +1284,12 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             // when is predicate
             boolean asPredicate = true;
 
+            boolean important = false;
             String displayName = null;
             Metadata metadata = fieldElement.getAnnotation(Metadata.class);
             if (metadata != null) {
                 displayName = metadata.displayName();
+                important = metadata.important();
             }
             boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
@@ -1293,7 +1304,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             final String kind = "element";
             EipOptionModel ep = createOption(name, displayName, kind, 
fieldTypeName, false, "", label, docComment, deprecated,
                     deprecationNote, false, null, oneOfTypes,
-                    asPredicate, false);
+                    asPredicate, false, important);
             eipOptions.add(ep);
         }
     }
@@ -1407,7 +1418,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
             String name, String displayName, String kind, String type, boolean 
required, String defaultValue, String label,
             String description, boolean deprecated,
             String deprecationNote, boolean enumType, Set<String> enums, 
Set<String> oneOfs, boolean asPredicate,
-            boolean isDuration) {
+            boolean isDuration, boolean important) {
         EipOptionModel option = new EipOptionModel();
         option.setName(name);
         option.setDisplayName(Strings.isNullOrEmpty(displayName) ? 
Strings.asTitle(name) : displayName);
@@ -1426,6 +1437,7 @@ public class SchemaGeneratorMojo extends 
AbstractGeneratorMojo {
         option.setEnums(enums != null && !enums.isEmpty() ? new 
ArrayList<>(enums) : null);
         option.setOneOfs(oneOfs != null && !oneOfs.isEmpty() ? new 
ArrayList<>(oneOfs) : null);
         option.setAsPredicate(asPredicate);
+        option.setImportant(important);
         return option;
     }
 
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateHeaderImportantHelper.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateHeaderImportantHelper.java
new file mode 100644
index 000000000000..7cbd21e70725
--- /dev/null
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/UpdateHeaderImportantHelper.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.maven.packaging;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.TreeSet;
+import java.util.stream.Stream;
+
+import javax.inject.Inject;
+
+import org.apache.camel.tooling.model.ComponentModel;
+import org.apache.camel.tooling.model.EipModel;
+import org.apache.camel.tooling.model.JsonMapper;
+import org.apache.camel.tooling.util.PackageHelper;
+import org.apache.camel.tooling.util.Strings;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProjectHelper;
+import org.codehaus.plexus.build.BuildContext;
+
+import static org.apache.camel.tooling.util.PackageHelper.findCamelDirectory;
+
+/**
+ * Updates the HeaderImportantHelper.java with the known important message 
headers
+ */
+@Mojo(name = "update-important-header-helper", threadSafe = true)
+public class UpdateHeaderImportantHelper extends AbstractGeneratorMojo {
+
+    private static final String KEYS_START_TOKEN = "// IMPORTANT-HEADER-KEYS: 
START";
+    private static final String KEYS_END_TOKEN = "// IMPORTANT-HEADER-KEYS: 
END";
+
+    @Parameter(defaultValue = 
"${project.basedir}/src/generated/resources/org/apache/camel/catalog/")
+    protected File jsonDir;
+
+    @Parameter(defaultValue = "${project.basedir}/")
+    protected File baseDir;
+
+    @Inject
+    public UpdateHeaderImportantHelper(MavenProjectHelper projectHelper, 
BuildContext buildContext) {
+        super(projectHelper, buildContext);
+    }
+
+    /**
+     * Execute goal.
+     *
+     * @throws MojoExecutionException execution of the main class or one of 
the threads it generated failed.
+     */
+    @Override
+    public void execute() throws MojoExecutionException {
+        File camelDir = findCamelDirectory(baseDir, "core/camel-util");
+        if (camelDir == null) {
+            getLog().debug("No core/camel-util folder found, skipping 
execution");
+            return;
+        }
+        List<Path> jsonFiles;
+        try (Stream<Path> stream = 
PackageHelper.findJsonFiles(jsonDir.toPath())) {
+            jsonFiles = stream.toList();
+        }
+        Set<String> importants = new TreeSet<>();
+
+        for (Path file : jsonFiles) {
+            final String name = PackageHelper.asName(file);
+
+            try {
+                String json = PackageHelper.loadText(file.toFile());
+                Object jo = Jsoner.deserialize(json);
+                JsonObject obj;
+                if (jo instanceof JsonObject) {
+                    obj = (JsonObject) jo;
+                } else {
+                    continue;
+                }
+
+                boolean isComponent = obj.getMap("component") != null;
+                boolean isEip = !isComponent && obj.getMap("model") != null;
+
+                // only check these kind
+                if (!isComponent && !isEip) {
+                    continue;
+                }
+
+                if (isComponent) {
+                    ComponentModel cm = 
JsonMapper.generateComponentModel(json);
+                    cm.getEndpointHeaders().forEach(o -> {
+                        if (o.isImportant()) {
+                            importants.add(o.getName());
+                        }
+                    });
+                } else if (isEip) {
+                    EipModel em = JsonMapper.generateEipModel(json);
+                    em.getExchangeProperties().forEach(o -> {
+                        if (o.isImportant()) {
+                            importants.add(o.getName());
+                        }
+                    });
+                }
+            } catch (Exception e) {
+                throw new MojoExecutionException("Error loading json: " + 
name, e);
+            }
+        }
+
+        getLog().info("There are " + importants.size()
+                      + " distinct important options across all the Camel 
components/eips");
+
+        try {
+            boolean updated = updateImportantHeaderKeys(camelDir, importants);
+            if (updated) {
+                getLog().info("Updated 
camel-util/src/main/java/org/apache/camel/util/ImportantHeaderUtils.java file");
+            } else {
+                getLog().debug("No changes to 
camel-util/src/main/java/org/apache/camel/util/ImportantHeaderUtils.java file");
+            }
+        } catch (Exception e) {
+            throw new MojoExecutionException("Error updating 
ImportantHeaderUtils.java", e);
+        }
+
+        try {
+            updateImportantHeaderJsonSchema(baseDir, importants);
+        } catch (Exception e) {
+            throw new MojoExecutionException("Error updating 
important-headers.json", e);
+        }
+    }
+
+    private boolean updateImportantHeaderKeys(File camelDir, Set<String> 
importants) throws Exception {
+        // load source code and update
+        File java = new File(camelDir, 
"src/main/java/org/apache/camel/util/ImportantHeaderUtils.java");
+        String text = PackageHelper.loadText(java);
+        String spaces20 = "                    ";
+        String spaces12 = "            ";
+
+        StringJoiner sb = new StringJoiner(",\n");
+        for (String name : importants) {
+            sb.add(spaces20 + "\"" + name + "\"");
+        }
+        String changed = sb.toString();
+
+        String existing = Strings.between(text, KEYS_START_TOKEN, 
KEYS_END_TOKEN);
+        if (existing != null) {
+            // remove leading line breaks etc
+            existing = existing.trim();
+            changed = changed.trim();
+            if (existing.equals(changed)) {
+                return false;
+            } else {
+                String before = Strings.before(text, KEYS_START_TOKEN);
+                String after = Strings.after(text, KEYS_END_TOKEN);
+                text = before + KEYS_START_TOKEN + "\n" + spaces20 + changed + 
"\n" + spaces12 + KEYS_END_TOKEN + after;
+                PackageHelper.writeText(java, text);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private void updateImportantHeaderJsonSchema(File camelDir, Set<String> 
secrets) throws Exception {
+        File target = new File(camelDir, 
"src/generated/resources/org/apache/camel/catalog/main/important-headers.json");
+        JsonArray arr = new JsonArray();
+        arr.addAll(secrets);
+        String json = JsonMapper.serialize(arr);
+        PackageHelper.writeText(target, json);
+    }
+
+}
diff --git 
a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java 
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
index 462df3cc4dca..c396d77fd2da 100644
--- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
+++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
@@ -175,4 +175,10 @@ public @interface Metadata {
      * Annotations data for Camel concepts such as components, EIP, etc.
      */
     String[] annotations() default {};
+
+    /**
+     * Whether this option is important
+     */
+    boolean important() default false;
+
 }

Reply via email to