You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2024/03/20 10:00:09 UTC

(camel) branch main updated: Pojo beans in camel-catalog (#13491)

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

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


The following commit(s) were added to refs/heads/main by this push:
     new c0931290558 Pojo beans in camel-catalog (#13491)
c0931290558 is described below

commit c0931290558005d216f6921d7229af25e95ccda9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Mar 20 11:00:03 2024 +0100

    Pojo beans in camel-catalog (#13491)
    
    CAMEL-17641: Generate json metadata for pojo beans in camel-core that end users can use such as AggregationStrategy implementations. And have that information in camel-catalog for tooling assistance.
---
 .../org/apache/camel/catalog/beans.properties      |  37 +++
 .../beans/CaffeineAggregationRepository.json       |  16 ++
 .../beans/CaffeineIdempotentRepository.json        |  16 ++
 .../beans/CassandraAggregationRepository.json      |  16 ++
 .../beans/CassandraIdempotentRepository.json       |  16 ++
 .../catalog/beans/DefaultHeaderFilterStrategy.json |  16 ++
 .../beans/EhcacheAggregationRepository.json        |  16 ++
 .../catalog/beans/EhcacheIdempotentRepository.json |  16 ++
 ...astichsearchBulkRequestAggregationStrategy.json |  15 +
 .../catalog/beans/Etcd3AggregationRepository.json  |  16 ++
 .../catalog/beans/FileIdempotentRepository.json    |  16 ++
 .../beans/GroupedBodyAggregationStrategy.json      |  15 +
 .../beans/GroupedExchangeAggregationStrategy.json  |  15 +
 .../beans/GroupedMessageAggregationStrategy.json   |  15 +
 .../beans/HazelcastAggregationRepository.json      |  16 ++
 .../beans/HazelcastIdempotentRepository.json       |  16 ++
 .../InfinispanEmbeddedAggregationRepository.json   |  16 ++
 .../InfinispanEmbeddedIdempotentRepository.json    |  16 ++
 .../InfinispanRemoteAggregationRepository.json     |  16 ++
 .../InfinispanRemoteIdempotentRepository.json      |  16 ++
 .../catalog/beans/JCacheAggregationRepository.json |  16 ++
 .../catalog/beans/JCacheIdempotentRepository.json  |  16 ++
 .../catalog/beans/JdbcAggregationRepository.json   |  16 ++
 .../catalog/beans/JdbcMessageIdRepository.json     |  16 ++
 .../catalog/beans/KafkaIdempotentRepository.json   |  16 ++
 .../beans/LevelDBAggregationRepository.json        |  16 ++
 .../catalog/beans/MemoryAggregationRepository.json |  16 ++
 .../catalog/beans/MemoryIdempotentRepository.json  |  16 ++
 .../catalog/beans/MongoDbIdempotentRepository.json |  16 ++
 .../OpensearchBulkRequestAggregationStrategy.json  |  15 +
 .../beans/SpringRedisIdempotentRepository.json     |  16 ++
 .../catalog/beans/StringAggregationStrategy.json   |  16 ++
 .../catalog/beans/TarAggregationStrategy.json      |  16 ++
 .../beans/UseLatestAggregationStrategy.json        |  15 +
 .../beans/UseOriginalAggregationStrategy.json      |  15 +
 .../catalog/beans/XsltAggregationStrategy.json     |  16 ++
 .../beans/XsltSaxonAggregationStrategy.json        |  16 ++
 .../catalog/beans/ZipAggregationStrategy.json      |  16 ++
 .../apache/camel/catalog/components/jcache.json    |  36 +--
 .../org/apache/camel/catalog/CamelCatalog.java     |  14 +
 .../catalog/CamelCatalogJSonSchemaResolver.java    |   7 +
 .../apache/camel/catalog/DefaultCamelCatalog.java  |  14 +
 .../camel/catalog/DefaultRuntimeProvider.java      |  16 ++
 .../org/apache/camel/catalog/RuntimeProvider.java  |  10 +
 .../org/apache/camel/catalog/CamelCatalogTest.java |  21 ++
 .../CaffeineAggregationRepositoryConfigurer.java   |  73 +++++
 .../CaffeineIdempotentRepositoryConfigurer.java    |  49 ++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/CaffeineAggregationRepository.json  |  16 ++
 .../camel/bean/CaffeineIdempotentRepository.json   |  16 ++
 ...ocessor.aggregate.CaffeineAggregationRepository |   2 +
 ...ocessor.idempotent.CaffeineIdempotentRepository |   2 +
 .../aggregate/CaffeineAggregationRepository.java   |  38 +--
 .../idempotent/CaffeineIdempotentRepository.java   |  23 +-
 .../CassandraAggregationRepositoryConfigurer.java  | 127 ++++++++
 .../CassandraIdempotentRepositoryConfigurer.java   |  85 ++++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/CassandraAggregationRepository.json |  16 ++
 .../camel/bean/CassandraIdempotentRepository.json  |  16 ++
 ...regate.cassandra.CassandraAggregationRepository |   2 +
 ...mpotent.cassandra.CassandraIdempotentRepository |   2 +
 .../cassandra/CassandraAggregationRepository.java  |  93 +++---
 .../NamedCassandraAggregationRepository.java       |   1 +
 .../cassandra/CassandraIdempotentRepository.java   |  70 +++--
 .../NamedCassandraIdempotentRepository.java        |   1 +
 .../EhcacheAggregationRepositoryConfigurer.java    |  79 +++++
 .../EhcacheIdempotentRepositoryConfigurer.java     |  49 ++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/EhcacheAggregationRepository.json   |  16 ++
 .../camel/bean/EhcacheIdempotentRepository.json    |  16 ++
 ...rocessor.aggregate.EhcacheAggregationRepository |   2 +
 ...rocessor.idempotent.EhcacheIdempotentRepository |   2 +
 .../aggregate/EhcacheAggregationRepository.java    |  40 +--
 .../idempotent/EhcacheIdempotentRepository.java    |  13 +-
 ...chBulkRequestAggregationStrategyConfigurer.java |  35 +++
 .../services/org/apache/camel/bean.properties      |   7 +
 ...astichsearchBulkRequestAggregationStrategy.json |  15 +
 ...on.ElastichsearchBulkRequestAggregationStrategy |   2 +
 ...stichsearchBulkRequestAggregationStrategy.java} |  11 +-
 .../Etcd3AggregationRepositoryConfigurer.java      |  91 ++++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/Etcd3AggregationRepository.json     |  16 ++
 ....processor.aggregate.Etcd3AggregationRepository |   2 +
 .../aggregate/Etcd3AggregationRepository.java      |  40 ++-
 .../HazelcastAggregationRepositoryConfigurer.java  |  79 +++++
 .../HazelcastIdempotentRepositoryConfigurer.java   |  35 +++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/HazelcastAggregationRepository.json |  16 ++
 .../camel/bean/HazelcastIdempotentRepository.json  |  16 ++
 ...regate.hazelcast.HazelcastAggregationRepository |   2 +
 ...mpotent.hazelcast.HazelcastIdempotentRepository |   2 +
 .../hazelcast/HazelcastAggregationRepository.java  |  86 +++---
 .../ReplicatedHazelcastAggregationRepository.java  |  19 +-
 .../hazelcast/HazelcastIdempotentRepository.java   |  32 ++-
 ...lcastAggregationRepositoryConstructorsTest.java |   9 -
 .../InfinispanAggregationRepository.java           |  51 ++--
 ...panEmbeddedAggregationRepositoryConfigurer.java |  85 ++++++
 ...spanEmbeddedIdempotentRepositoryConfigurer.java |  61 ++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../InfinispanEmbeddedAggregationRepository.json   |  16 ++
 .../InfinispanEmbeddedIdempotentRepository.json    |  16 ++
 ...mbedded.InfinispanEmbeddedAggregationRepository |   2 +
 ...embedded.InfinispanEmbeddedIdempotentRepository |   2 +
 .../InfinispanEmbeddedAggregationRepository.java   |  36 ++-
 .../InfinispanEmbeddedIdempotentRepository.java    |  31 +-
 ...ispanRemoteAggregationRepositoryConfigurer.java |  85 ++++++
 ...nispanRemoteIdempotentRepositoryConfigurer.java |  55 ++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../InfinispanRemoteAggregationRepository.json     |  16 ++
 .../bean/InfinispanRemoteIdempotentRepository.json |  16 ++
 ...an.remote.InfinispanRemoteAggregationRepository |   2 +
 ...pan.remote.InfinispanRemoteIdempotentRepository |   2 +
 .../InfinispanRemoteAggregationRepository.java     |  42 ++-
 .../InfinispanRemoteIdempotentRepository.java      |  28 +-
 .../JCacheAggregationRepositoryConfigurer.java     |  67 +++++
 .../JCacheIdempotentRepositoryConfigurer.java      |  55 ++++
 .../org/apache/camel/component/jcache/jcache.json  |  36 +--
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/JCacheAggregationRepository.json    |  16 ++
 .../camel/bean/JCacheIdempotentRepository.json     |  16 ++
 ...processor.aggregate.JCacheAggregationRepository |   2 +
 ...processor.idempotent.JCacheIdempotentRepository |   2 +
 .../component/jcache/JCacheConfiguration.java      |  21 +-
 .../aggregate/JCacheAggregationRepository.java     |  15 +-
 .../idempotent/JCacheIdempotentRepository.java     |  15 +-
 .../kafka/KafkaIdempotentRepositoryConfigurer.java |  67 +++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/KafkaIdempotentRepository.json      |  16 ++
 ...ssor.idempotent.kafka.KafkaIdempotentRepository |   2 +
 .../kafka/KafkaIdempotentRepository.java           |  89 +++---
 .../LevelDBAggregationRepositoryConfigurer.java    | 103 +++++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/LevelDBAggregationRepository.json   |  16 ++
 ....component.leveldb.LevelDBAggregationRepository |   2 +
 .../leveldb/LevelDBAggregationRepository.java      |  33 ++-
 .../MongoDbIdempotentRepositoryConfigurer.java     |  61 ++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/MongoDbIdempotentRepository.json    |  16 ++
 ...rocessor.idempotent.MongoDbIdempotentRepository |   2 +
 .../idempotent/MongoDbIdempotentRepository.java    |  18 +-
 .../integration/MongoDbIdempotentRepositoryIT.java |   1 +
 ...chBulkRequestAggregationStrategyConfigurer.java |  35 +++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../OpensearchBulkRequestAggregationStrategy.json  |  15 +
 ...gation.OpensearchBulkRequestAggregationStrategy |   2 +
 ... OpensearchBulkRequestAggregationStrategy.java} |   8 +-
 .../aggregate/RedisAggregationRepository.java      |  40 ++-
 .../SpringRedisIdempotentRepositoryConfigurer.java |  49 ++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../bean/SpringRedisIdempotentRepository.json      |  16 ++
 ...ssor.idempotent.SpringRedisIdempotentRepository |   2 +
 ...y.java => SpringRedisIdempotentRepository.java} |  61 ++--
 ... => SpringRedisStringIdempotentRepository.java} |   6 +-
 .../RedisStringIdempotentRepositoryManualIT.java   |   4 +-
 .../RedisStringIdempotentRepositoryTest.java       |  12 +-
 ...va => SpringRedisIdempotentRepositoryTest.java} |   8 +-
 .../resources/RedisComponentSpringTest-context.xml |   2 +-
 .../jdbc/JdbcAggregationRepositoryConfigurer.java  | 136 +++++++++
 .../jdbc/JdbcMessageIdRepositoryConfigurer.java    | 109 +++++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/JdbcAggregationRepository.json      |  16 ++
 .../apache/camel/bean/JdbcMessageIdRepository.json |  16 ++
 ...cessor.aggregate.jdbc.JdbcAggregationRepository |   2 +
 ...ocessor.idempotent.jdbc.JdbcMessageIdRepository |   2 +
 .../jdbc/ClusteredJdbcAggregationRepository.java   |   2 +-
 .../ClusteredPostgresAggregationRepository.java    |   2 +-
 .../aggregate/jdbc/JdbcAggregationRepository.java  |  93 ++++--
 .../jdbc/PostgresAggregationRepository.java        |   2 +-
 .../jdbc/AbstractJdbcMessageIdRepository.java      |  12 +-
 .../idempotent/jdbc/JdbcMessageIdRepository.java   |  16 +-
 .../jdbc/JdbcAggregateStoreAsTextTest.java         |   3 +-
 .../tarfile/TarAggregationStrategyConfigurer.java  |  61 ++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../apache/camel/bean/TarAggregationStrategy.json  |  16 ++
 ...cessor.aggregate.tarfile.TarAggregationStrategy |   2 +
 .../aggregate/tarfile/TarAggregationStrategy.java  |  14 +
 .../XsltSaxonAggregationStrategyConfigurer.java    |  67 +++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/XsltSaxonAggregationStrategy.json   |  16 ++
 ...mponent.xslt.saxon.XsltSaxonAggregationStrategy |   2 +
 .../xslt/saxon/XsltSaxonAggregationStrategy.java   |  26 ++
 .../xslt/XsltAggregationStrategyConfigurer.java    |  67 +++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../apache/camel/bean/XsltAggregationStrategy.json |  16 ++
 ...he.camel.component.xslt.XsltAggregationStrategy |   2 +
 .../component/xslt/XsltAggregationStrategy.java    |  33 ++-
 .../zipfile/ZipAggregationStrategyConfigurer.java  |  79 +++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../apache/camel/bean/ZipAggregationStrategy.json  |  16 ++
 ...cessor.aggregate.zipfile.ZipAggregationStrategy |   2 +
 .../aggregate/zipfile/ZipAggregationStrategy.java  |  39 +++
 .../java/org/apache/camel/CatalogCamelContext.java |   7 +
 .../apache/camel/catalog/JSonSchemaResolver.java   |   8 +
 .../main/java/org/apache/camel/spi/Configurer.java |   5 +
 .../spi/RecoverableAggregationRepository.java      |  19 +-
 .../camel/impl/engine/AbstractCamelContext.java    |  11 +
 .../camel/catalog/impl/AbstractCamelCatalog.java   |  10 +
 .../impl/CamelContextJSonSchemaResolver.java       |  10 +
 .../GroupedBodyAggregationStrategyConfigurer.java  |  35 +++
 ...oupedExchangeAggregationStrategyConfigurer.java |  35 +++
 ...roupedMessageAggregationStrategyConfigurer.java |  35 +++
 .../MemoryAggregationRepositoryConfigurer.java     |  49 ++++
 .../StringAggregationStrategyConfigurer.java       |  49 ++++
 .../UseLatestAggregationStrategyConfigurer.java    |  35 +++
 .../UseOriginalAggregationStrategyConfigurer.java  |  35 +++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/GroupedBodyAggregationStrategy.json |  15 +
 .../bean/GroupedExchangeAggregationStrategy.json   |  15 +
 .../bean/GroupedMessageAggregationStrategy.json    |  15 +
 .../camel/bean/MemoryAggregationRepository.json    |  16 ++
 .../camel/bean/StringAggregationStrategy.json      |  16 ++
 .../camel/bean/UseLatestAggregationStrategy.json   |  15 +
 .../camel/bean/UseOriginalAggregationStrategy.json |  15 +
 .../services/org/apache/camel/beans.properties     |   7 +
 ...cessor.aggregate.GroupedBodyAggregationStrategy |   2 +
 ...or.aggregate.GroupedExchangeAggregationStrategy |   2 +
 ...sor.aggregate.GroupedMessageAggregationStrategy |   2 +
 ...processor.aggregate.MemoryAggregationRepository |   2 +
 ...l.processor.aggregate.StringAggregationStrategy |   2 +
 ...rocessor.aggregate.UseLatestAggregationStrategy |   2 +
 ...cessor.aggregate.UseOriginalAggregationStrategy |   2 +
 .../processor/aggregate/AggregateProcessor.java    |   2 +-
 .../aggregate/GroupedBodyAggregationStrategy.java  |   8 +
 .../GroupedExchangeAggregationStrategy.java        |   8 +
 .../GroupedMessageAggregationStrategy.java         |   8 +
 .../aggregate/MemoryAggregationRepository.java     |  18 +-
 .../aggregate/StringAggregationStrategy.java       |  24 ++
 .../aggregate/UseLatestAggregationStrategy.java    |   8 +
 .../aggregate/UseOriginalAggregationStrategy.java  |   8 +
 .../FileIdempotentRepositoryConfigurerTest.java    |  63 ++++
 .../DefaultHeaderFilterStrategyConfigurer.java     |  90 ++++++
 .../FileIdempotentRepositoryConfigurer.java        |  67 +++++
 .../MemoryIdempotentRepositoryConfigurer.java      |  49 ++++
 .../services/org/apache/camel/bean.properties      |   7 +
 .../camel/bean/DefaultHeaderFilterStrategy.json    |  16 ++
 .../camel/bean/FileIdempotentRepository.json       |  16 ++
 .../camel/bean/MemoryIdempotentRepository.json     |  16 ++
 ...pache.camel.support.DefaultHeaderFilterStrategy |   2 +
 ...t.processor.idempotent.FileIdempotentRepository |   2 +
 ...processor.idempotent.MemoryIdempotentRepository |   2 +
 .../camel/support/DefaultHeaderFilterStrategy.java |  44 ++-
 .../idempotent/FileIdempotentRepository.java       |  15 +-
 .../idempotent/MemoryIdempotentRepository.java     |   8 +
 .../camel/yaml/io/ModelJSonSchemaResolver.java     |   5 +
 .../ROOT/pages/camel-4x-upgrade-guide-4_5.adoc     |  10 +
 .../component/ComponentsBuilderFactory.java        |   2 +-
 ...LangchainEmbeddingsComponentBuilderFactory.java |   4 +-
 .../src/generated/resources/metadata.json          |   4 +-
 .../endpoint/dsl/JCacheEndpointBuilderFactory.java | 204 ++++++-------
 .../DependencyDownloaderClassResolver.java         |  23 ++
 .../apache/camel/kotlin/components/JcacheUriDsl.kt |  14 +-
 .../org/apache/camel/tooling/model/JsonMapper.java |  39 +++
 .../java/org/apache/camel/tooling/model/Kind.java  |   2 +
 .../apache/camel/tooling/model/PojoBeanModel.java  |  34 ++-
 .../packaging/AbstractGenerateConfigurerMojo.java  |  47 ++-
 .../packaging/EndpointSchemaGeneratorMojo.java     |  82 +-----
 .../maven/packaging/GenerateComponentMojo.java     |   2 +
 .../apache/camel/maven/packaging/GenerateMojo.java |   2 +
 .../maven/packaging/GeneratePojoBeanMojo.java      | 319 +++++++++++++++++++++
 .../apache/camel/maven/packaging/MojoHelper.java   | 104 +++++++
 .../camel/maven/packaging/PrepareCatalogMojo.java  |  69 ++++-
 261 files changed, 5841 insertions(+), 660 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans.properties
new file mode 100644
index 00000000000..6482327ff35
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans.properties
@@ -0,0 +1,37 @@
+CaffeineAggregationRepository
+CaffeineIdempotentRepository
+CassandraAggregationRepository
+CassandraIdempotentRepository
+DefaultHeaderFilterStrategy
+EhcacheAggregationRepository
+EhcacheIdempotentRepository
+ElastichsearchBulkRequestAggregationStrategy
+Etcd3AggregationRepository
+FileIdempotentRepository
+GroupedBodyAggregationStrategy
+GroupedExchangeAggregationStrategy
+GroupedMessageAggregationStrategy
+HazelcastAggregationRepository
+HazelcastIdempotentRepository
+InfinispanEmbeddedAggregationRepository
+InfinispanEmbeddedIdempotentRepository
+InfinispanRemoteAggregationRepository
+InfinispanRemoteIdempotentRepository
+JCacheAggregationRepository
+JCacheIdempotentRepository
+JdbcAggregationRepository
+JdbcMessageIdRepository
+KafkaIdempotentRepository
+LevelDBAggregationRepository
+MemoryAggregationRepository
+MemoryIdempotentRepository
+MongoDbIdempotentRepository
+OpensearchBulkRequestAggregationStrategy
+SpringRedisIdempotentRepository
+StringAggregationStrategy
+TarAggregationStrategy
+UseLatestAggregationStrategy
+UseOriginalAggregationStrategy
+XsltAggregationStrategy
+XsltSaxonAggregationStrategy
+ZipAggregationStrategy
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CaffeineAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CaffeineAggregationRepository.json
new file mode 100644
index 00000000000..14de19f8f81
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CaffeineAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "CaffeineAggregationRepository",
+    "javaType": "org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Caffeine Aggregation Repository",
+    "description": "Aggregation repository that uses Caffeine Cache to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-caffeine",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "useRecovery": { "index": 0, "kind": "property", "displayName": "Use Recovery", "required": false, "type": "object", "javaType": "org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "true", "description": "Whether or not recovery is enabled" }, "deadLetterUri": { "index": 1, "kind": "property", "displayName": "Dead Letter Uri", "required": false, "type": "obje [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CaffeineIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CaffeineIdempotentRepository.json
new file mode 100644
index 00000000000..dfc7548e400
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CaffeineIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "CaffeineIdempotentRepository",
+    "javaType": "org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Caffeine Idempotent Repository",
+    "description": "Idempotent repository that uses Caffiene cache to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-caffeine",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": false, "type": "object", "javaType": "org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "CaffeineIdempotentRepository", "description": "Name of cache" } }
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CassandraAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CassandraAggregationRepository.json
new file mode 100644
index 00000000000..c05e5b56162
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CassandraAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "CassandraAggregationRepository",
+    "javaType": "org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Cassandra Aggregation Repository",
+    "description": "Aggregation repository that uses Cassandra table to store exchanges. Advice: use LeveledCompaction for this table and tune read\/write consistency levels.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-cassandraql",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "sessionHolder": { "index": 0, "kind": "property", "displayName": "Session Holder", "required": true, "type": "object", "javaType": "org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Cassandra session" }, "table": { "index": 1, "kind": "property", "displayName": "Table", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.cassandra [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CassandraIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CassandraIdempotentRepository.json
new file mode 100644
index 00000000000..78269b7e649
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/CassandraIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "CassandraIdempotentRepository",
+    "javaType": "org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Cassandra Idempotent Repository",
+    "description": "Idempotent repository that uses Cassandra table to store message ids. Advice: use LeveledCompaction for this table and tune read\/write consistency levels.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-cassandraql",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "session": { "index": 0, "kind": "property", "displayName": "Session", "required": true, "type": "object", "javaType": "org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Cassandra session" }, "table": { "index": 1, "kind": "property", "displayName": "Table", "required": false, "type": "object", "javaType": "org.apache.camel.processor.idempotent.cassandra.CassandraId [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/DefaultHeaderFilterStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/DefaultHeaderFilterStrategy.json
new file mode 100644
index 00000000000..db72da32c2e
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/DefaultHeaderFilterStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "DefaultHeaderFilterStrategy",
+    "javaType": "org.apache.camel.support.DefaultHeaderFilterStrategy",
+    "interfaceType": "org.apache.camel.spi.HeaderFilterStrategy",
+    "title": "Default Header Filter Strategy",
+    "description": "The default header filtering strategy. Users can configure which headers is allowed or denied.",
+    "deprecated": true,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-support",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "inFilter": { "index": 0, "kind": "property", "displayName": "In Filter", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the in direction filter set. The in direction is referred to copying headers from an external message to a Camel message. Multiple patterns can be separated by comma" }, "outFilter": { "index": 1, "kind": "property", "displayName": "Out Filter", "req [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/EhcacheAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/EhcacheAggregationRepository.json
new file mode 100644
index 00000000000..eed304ee999
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/EhcacheAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "EhcacheAggregationRepository",
+    "javaType": "org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Ehcache Aggregation Repository",
+    "description": "Aggregation repository that uses Caffeine Cache to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-ehcache",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "allowSerializedHeaders": { "index": 1, "kind": "property", "displayName": "Allow Serialized Headers", "label": "advanced", "required": false, "type": "object", "javaTyp [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/EhcacheIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/EhcacheIdempotentRepository.json
new file mode 100644
index 00000000000..8cc0d729756
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/EhcacheIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "EhcacheIdempotentRepository",
+    "javaType": "org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Ehcache Idempotent Repository",
+    "description": "Idempotent repository that uses EHCache cache to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-ehcache",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": false, "type": "object", "javaType": "org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "EhcacheIdempotentRepository", "description": "Name of cache" } }
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/ElastichsearchBulkRequestAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/ElastichsearchBulkRequestAggregationStrategy.json
new file mode 100644
index 00000000000..19e93a9e8df
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/ElastichsearchBulkRequestAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "ElastichsearchBulkRequestAggregationStrategy",
+    "javaType": "org.apache.camel.component.es.aggregation.ElastichsearchBulkRequestAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Elastichsearch Bulk Request Aggregation Strategy",
+    "description": "Aggregates two ElasticSearch BulkOperation into a single BulkRequest",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-elasticsearch",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/Etcd3AggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/Etcd3AggregationRepository.json
new file mode 100644
index 00000000000..75a6d2e53a6
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/Etcd3AggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "Etcd3AggregationRepository",
+    "javaType": "org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Etcd3 Aggregation Repository",
+    "description": "Aggregation repository that uses Etcd3 to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-etcd3",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "endpoint": { "index": 0, "kind": "property", "displayName": "Endpoint", "required": true, "type": "object", "javaType": "org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "URL to Etcd3 service" }, "prefixName": { "index": 1, "kind": "property", "displayName": "Prefix Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.etcd3.processor [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/FileIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/FileIdempotentRepository.json
new file mode 100644
index 00000000000..b90fd10b9f5
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/FileIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "FileIdempotentRepository",
+    "javaType": "org.apache.camel.support.processor.idempotent.FileIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "File Idempotent Repository",
+    "description": "A file based IdempotentRepository.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-support",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "fileStore": { "index": 0, "kind": "property", "displayName": "File Store", "required": true, "type": "object", "javaType": "org.apache.camel.support.processor.idempotent.FileIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "File name of the repository (incl directory)" }, "maxFileStoreSize": { "index": 1, "kind": "property", "displayName": "Max File Store Size", "required": false, "type": "object", "javaType": "org.apach [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedBodyAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedBodyAggregationStrategy.json
new file mode 100644
index 00000000000..10edccd31e1
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedBodyAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedBodyAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Body Aggregation Strategy",
+    "description": "Aggregate body of input Message into a single combined Exchange holding all the aggregated bodies in a List of type Object as the message body. This aggregation strategy can be used in combination with Splitter to batch messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedExchangeAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedExchangeAggregationStrategy.json
new file mode 100644
index 00000000000..7ba11aca0c4
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedExchangeAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedExchangeAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Exchange Aggregation Strategy",
+    "description": "Aggregate all Exchanges into a single combined Exchange holding all the aggregated exchanges in a List of Exchange as the message body. This aggregation strategy can be used in combination with Splitter to batch messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedMessageAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedMessageAggregationStrategy.json
new file mode 100644
index 00000000000..a03cad939d9
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/GroupedMessageAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedMessageAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.GroupedMessageAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Message Aggregation Strategy",
+    "description": "Aggregate all Message into a single combined Exchange holding all the aggregated messages in a List of Message as the message body. This aggregation strategy can be used in combination with Splitter to batch messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/HazelcastAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/HazelcastAggregationRepository.json
new file mode 100644
index 00000000000..d21f0647b3f
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/HazelcastAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "HazelcastAggregationRepository",
+    "javaType": "org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Hazelcast Aggregation Repository",
+    "description": "Aggregation repository that uses Hazelcast Cache to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-hazelcast",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "mapName": { "index": 0, "kind": "property", "displayName": "Map Name", "required": true, "type": "object", "javaType": "org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache to use" }, "hazelcastInstance": { "index": 1, "kind": "property", "displayName": "Hazelcast Instance", "required": false, "type": "object", "javaType": "org.apache.camel.processor.agg [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/HazelcastIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/HazelcastIdempotentRepository.json
new file mode 100644
index 00000000000..87c881c225e
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/HazelcastIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "HazelcastIdempotentRepository",
+    "javaType": "org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Hazelcast Idempotent Repository",
+    "description": "Idempotent repository that uses Hazelcast cache to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-hazelcast",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "repositoryName": { "index": 0, "kind": "property", "displayName": "Repository Name", "required": false, "type": "object", "javaType": "org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "HazelcastIdempotentRepository", "description": "Name of cache to use" }, "hazelcastInstance": { "index": 1, "kind": "property", "displayName": "Hazelcast Instance", "required": fals [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanEmbeddedAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanEmbeddedAggregationRepository.json
new file mode 100644
index 00000000000..d15dd4d8018
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanEmbeddedAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "InfinispanEmbeddedAggregationRepository",
+    "javaType": "org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Infinispan Embedded Aggregation Repository",
+    "description": "Aggregation repository that uses embedded Infinispan to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-infinispan-embedded",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "configuration": { "index": 1, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.infini [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanEmbeddedIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanEmbeddedIdempotentRepository.json
new file mode 100644
index 00000000000..2704dc07f79
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanEmbeddedIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "InfinispanEmbeddedIdempotentRepository",
+    "javaType": "org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Infinispan Embedded Idempotent Repository",
+    "description": "Idempotent repository that uses embedded Infinispan to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-infinispan-embedded",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "configuration": { "index": 1, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.infinis [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanRemoteAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanRemoteAggregationRepository.json
new file mode 100644
index 00000000000..3a9fbe50d11
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanRemoteAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "InfinispanRemoteAggregationRepository",
+    "javaType": "org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Infinispan Remote Aggregation Repository",
+    "description": "Aggregation repository that uses remote Infinispan to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-infinispan",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "configuration": { "index": 1, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.infinispan [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanRemoteIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanRemoteIdempotentRepository.json
new file mode 100644
index 00000000000..b4d7349e455
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/InfinispanRemoteIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "InfinispanRemoteIdempotentRepository",
+    "javaType": "org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Infinispan Remote Idempotent Repository",
+    "description": "Idempotent repository that uses remote Infinispan to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-infinispan",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "configuration": { "index": 1, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.infinispan. [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JCacheAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JCacheAggregationRepository.json
new file mode 100644
index 00000000000..5a5cf747868
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JCacheAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "JCacheAggregationRepository",
+    "javaType": "org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "JCache Aggregation Repository",
+    "description": "Aggregation repository that uses JCache to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-jcache",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "configuration": { "index": 0, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Configuration for JCache" }, "optimistic": { "index": 1, "kind": "property", "displayName": "Optimistic", "required": false, "type": "object", "javaType": "org.apache.camel.componen [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JCacheIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JCacheIdempotentRepository.json
new file mode 100644
index 00000000000..76e7c1861cb
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JCacheIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "JCacheIdempotentRepository",
+    "javaType": "org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "JCache Idempotent Repository",
+    "description": "Idempotent repository that uses JCache to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-jcache",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "configuration": { "index": 0, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Configuration for JCache" } }
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcAggregationRepository.json
new file mode 100644
index 00000000000..44957e05cba
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "JdbcAggregationRepository",
+    "javaType": "org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository",
+    "interfaceType": "org.apache.camel.spi.AggregationRepository",
+    "title": "Jdbc Aggregation Repository",
+    "description": "Aggregation repository that uses SQL database to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-sql",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "dataSource": { "index": 0, "kind": "property", "displayName": "Data Source", "required": true, "type": "object", "javaType": "org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "The DataSource to use for connecting to the database" }, "transactionManager": { "index": 1, "kind": "property", "displayName": "Transaction Manager", "required": true, "type": "object", "javaType": "o [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcMessageIdRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcMessageIdRepository.json
new file mode 100644
index 00000000000..0c49743805b
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/JdbcMessageIdRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "JdbcMessageIdRepository",
+    "javaType": "org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Jdbc Message Id Repository",
+    "description": "Idempotent repository that uses a SQL database to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-sql",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "tableName": { "index": 0, "kind": "property", "displayName": "Table Name", "required": false, "type": "object", "javaType": "org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "CAMEL_MESSAGEPROCESSED", "description": "The name of the table to use in the database" }, "createTableIfNotExists": { "index": 1, "kind": "property", "displayName": "Create Table If Not Exists", "requir [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/KafkaIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/KafkaIdempotentRepository.json
new file mode 100644
index 00000000000..ef73b04be6c
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/KafkaIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "KafkaIdempotentRepository",
+    "javaType": "org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Kafka Idempotent Repository",
+    "description": "Idempotent repository that uses Kafka to store message ids. Uses a local cache of previously seen Message IDs. The topic used must be unique per logical repository (i.e. two routes de-duplicate using different repositories, and different topics) On startup, the instance consumes the full content of the topic, rebuilding the cache to the latest state.",
+    "deprecated": true,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-kafka",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "topic": { "index": 0, "kind": "property", "displayName": "Topic", "required": true, "type": "object", "javaType": "org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the name of the Kafka topic used by this idempotent repository. Each functionally-separate repository should use a different topic." }, "bootstrapServers": { "index": 1, "kind": "property", "displayName":  [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LevelDBAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LevelDBAggregationRepository.json
new file mode 100644
index 00000000000..43bc883d6a5
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/LevelDBAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "LevelDBAggregationRepository",
+    "javaType": "org.apache.camel.component.leveldb.LevelDBAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Level DBAggregation Repository",
+    "description": "Aggregation repository that uses LevelDB to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-leveldb",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "persistentFileName": { "index": 0, "kind": "property", "displayName": "Persistent File Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.leveldb.LevelDBAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of file to use for storing data" }, "repositoryName": { "index": 1, "kind": "property", "displayName": "Repository Name", "required": true, "type": "object", "javaType": "org.apache.c [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryAggregationRepository.json
new file mode 100644
index 00000000000..89401b1e5fe
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "MemoryAggregationRepository",
+    "javaType": "org.apache.camel.processor.aggregate.MemoryAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Memory Aggregation Repository",
+    "description": "A memory based AggregationRepository which stores Exchange in memory only.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "optimisticLocking": { "index": 0, "kind": "property", "displayName": "Optimistic Locking", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.MemoryAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Whether to use optimistic locking" } }
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json
new file mode 100644
index 00000000000..a70bbdcdf2e
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "MemoryIdempotentRepository",
+    "javaType": "org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Memory Idempotent Repository",
+    "description": "A memory based IdempotentRepository.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-support",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheSize": { "index": 0, "kind": "property", "displayName": "Cache Size", "required": false, "type": "object", "javaType": "org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "description": "Maximum elements that can be stored in-memory" } }
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MongoDbIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MongoDbIdempotentRepository.json
new file mode 100644
index 00000000000..749f99167b9
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MongoDbIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "MongoDbIdempotentRepository",
+    "javaType": "org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Mongo Db Idempotent Repository",
+    "description": "Idempotent repository that uses MongoDB to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-mongodb",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "mongoClient": { "index": 0, "kind": "property", "displayName": "Mongo Client", "required": true, "type": "object", "javaType": "org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "The MongoClient to use for connecting to the MongoDB server" }, "dbName": { "index": 1, "kind": "property", "displayName": "Db Name", "required": true, "type": "object", "javaType": " [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/OpensearchBulkRequestAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/OpensearchBulkRequestAggregationStrategy.json
new file mode 100644
index 00000000000..482106ac075
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/OpensearchBulkRequestAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "OpensearchBulkRequestAggregationStrategy",
+    "javaType": "org.apache.camel.component.opensearch.aggregation.OpensearchBulkRequestAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Opensearch Bulk Request Aggregation Strategy",
+    "description": "Aggregates two OpenSearch BulkOperation into a single BulkRequest",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-opensearch",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/SpringRedisIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/SpringRedisIdempotentRepository.json
new file mode 100644
index 00000000000..a47bd531d89
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/SpringRedisIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "SpringRedisIdempotentRepository",
+    "javaType": "org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Spring Redis Idempotent Repository",
+    "description": "Idempotent repository that uses Redis to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-spring-redis",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "repositoryName": { "index": 0, "kind": "property", "displayName": "Repository Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of repository" }, "redisConfiguration": { "index": 1, "kind": "property", "displayName": "Redis Configuration", "required": false, "type": "object", "javaType": "org.apac [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/StringAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/StringAggregationStrategy.json
new file mode 100644
index 00000000000..b1b1279d2b3
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/StringAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "StringAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.StringAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "String Aggregation Strategy",
+    "description": "Aggregate result of pick expression into a single combined Exchange holding all the aggregated bodies in a String as the message body. This aggregation strategy can used in combination with Splitter to batch messages",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "delimiter": { "index": 0, "kind": "property", "displayName": "Delimiter", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.StringAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Delimiter used for joining strings together." } }
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/TarAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/TarAggregationStrategy.json
new file mode 100644
index 00000000000..f089769724c
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/TarAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "TarAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Tar Aggregation Strategy",
+    "description": "AggregationStrategy to combine together incoming messages into a tar file. Please note that this aggregation strategy requires eager completion check to work properly.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-tarfile",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "filePrefix": { "index": 0, "kind": "property", "displayName": "File Prefix", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the prefix that will be used when creating the TAR filename." }, "fileSuffix": { "index": 1, "kind": "property", "displayName": "File Suffix", "required": false, "type": "object", "javaType": "or [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseLatestAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseLatestAggregationStrategy.json
new file mode 100644
index 00000000000..5d73c66d791
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseLatestAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "UseLatestAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.UseLatestAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Use Latest Aggregation Strategy",
+    "description": "An AggregationStrategy which just uses the latest exchange which is useful for status messages where old status messages have no real value. Another example is things like market data prices, where old stock prices are not that relevant, only the current price is.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseOriginalAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseOriginalAggregationStrategy.json
new file mode 100644
index 00000000000..7ab066f5d79
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/UseOriginalAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "UseOriginalAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Use Original Aggregation Strategy",
+    "description": "An AggregationStrategy which just uses the original exchange which can be needed when you want to preserve the original Exchange. For example when splitting an Exchange and then you may want to keep routing using the original Exchange.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/XsltAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/XsltAggregationStrategy.json
new file mode 100644
index 00000000000..8728d9f2a37
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/XsltAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "XsltAggregationStrategy",
+    "javaType": "org.apache.camel.component.xslt.XsltAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Xslt Aggregation Strategy",
+    "description": "The XSLT Aggregation Strategy enables you to use XSL stylesheets to aggregate messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-xslt",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "xslFile": { "index": 0, "kind": "property", "displayName": "Xsl File", "required": true, "type": "object", "javaType": "org.apache.camel.component.xslt.XsltAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the XSL transformation file to use" }, "propertyName": { "index": 1, "kind": "property", "displayName": "Property Name", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.Xslt [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/XsltSaxonAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/XsltSaxonAggregationStrategy.json
new file mode 100644
index 00000000000..81e5ceb406c
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/XsltSaxonAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "XsltSaxonAggregationStrategy",
+    "javaType": "org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Xslt Saxon Aggregation Strategy",
+    "description": "The XSLT Aggregation Strategy enables you to use XSL stylesheets to aggregate messages (uses Saxon).",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-xslt-saxon",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "xslFile": { "index": 0, "kind": "property", "displayName": "Xsl File", "required": true, "type": "object", "javaType": "org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the XSL transformation file to use" }, "propertyName": { "index": 1, "kind": "property", "displayName": "Property Name", "required": false, "type": "object", "javaType": "org.apache.camel.componen [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/ZipAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/ZipAggregationStrategy.json
new file mode 100644
index 00000000000..f7b20124fa4
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/ZipAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "ZipAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Zip Aggregation Strategy",
+    "description": "AggregationStrategy to zip together incoming messages into a zip file. Please note that this aggregation strategy requires eager completion check to work properly.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-zipfile",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "filePrefix": { "index": 0, "kind": "property", "displayName": "File Prefix", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the prefix that will be used when creating the ZIP filename." }, "fileSuffix": { "index": 1, "kind": "property", "displayName": "File Suffix", "required": false, "type": "object", "javaType": "or [...]
+  }
+}
+
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jcache.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jcache.json
index 6a82e6806d9..5e8f5ff9eb2 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jcache.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jcache.json
@@ -44,24 +44,24 @@
   },
   "properties": {
     "cacheName": { "index": 0, "kind": "path", "displayName": "Cache Name", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the cache" },
-    "cacheConfiguration": { "index": 1, "kind": "parameter", "displayName": "Cache Configuration", "group": "common", "label": "", "required": false, "type": "object", "javaType": "javax.cache.configuration.Configuration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "A Configuration for the Cache" },
-    "cacheConfigurationProperties": { "index": 2, "kind": "parameter", "displayName": "Cache Configuration Properties", "group": "common", "label": "", "required": false, "type": "object", "javaType": "java.util.Properties", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The Properties for the javax.cache.spi.CachingProvider to create the CacheM [...]
-    "cachingProvider": { "index": 3, "kind": "parameter", "displayName": "Caching Provider", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The fully qualified class name of the javax.cache.spi.CachingProvider" },
-    "configurationUri": { "index": 4, "kind": "parameter", "displayName": "Configuration Uri", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "An implementation specific URI for the CacheManager" },
-    "managementEnabled": { "index": 5, "kind": "parameter", "displayName": "Management Enabled", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Whether management gathering is enabled" },
-    "readThrough": { "index": 6, "kind": "parameter", "displayName": "Read Through", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If read-through caching should be used" },
-    "statisticsEnabled": { "index": 7, "kind": "parameter", "displayName": "Statistics Enabled", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Whether statistics gathering is enabled" },
-    "storeByValue": { "index": 8, "kind": "parameter", "displayName": "Store By Value", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If cache should use store-by-value or store-by-reference semantics" },
-    "writeThrough": { "index": 9, "kind": "parameter", "displayName": "Write Through", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If write-through caching should be used" },
-    "filteredEvents": { "index": 10, "kind": "parameter", "displayName": "Filtered Events", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "CREATED", "UPDATED", "REMOVED", "EXPIRED" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Events a consumer should filter (multiple [...]
-    "oldValueRequired": { "index": 11, "kind": "parameter", "displayName": "Old Value Required", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "if the old value is required for events" },
-    "synchronous": { "index": 12, "kind": "parameter", "displayName": "Synchronous", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "if the event listener should block the thread causing the event" },
-    "bridgeErrorHandler": { "index": 13, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming [...]
-    "eventFilters": { "index": 14, "kind": "parameter", "displayName": "Event Filters", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<javax.cache.event.CacheEntryEventFilter>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The CacheEntryEventFilter. If using eventFi [...]
-    "exceptionHandler": { "index": 15, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By de [...]
-    "exchangePattern": { "index": 16, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
-    "action": { "index": 17, "kind": "parameter", "displayName": "Action", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "To configure using a cache operation by default. If an operation in the message header, then the operation from th [...]
-    "lazyStartProducer": { "index": 18, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...]
+    "cacheConfigurationProperties": { "index": 1, "kind": "parameter", "displayName": "Cache Configuration Properties", "group": "common", "label": "", "required": false, "type": "object", "javaType": "java.util.Properties", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The Properties for the javax.cache.spi.CachingProvider to create the CacheM [...]
+    "cachingProvider": { "index": 2, "kind": "parameter", "displayName": "Caching Provider", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The fully qualified class name of the javax.cache.spi.CachingProvider" },
+    "configurationUri": { "index": 3, "kind": "parameter", "displayName": "Configuration Uri", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "An implementation specific URI for the CacheManager" },
+    "managementEnabled": { "index": 4, "kind": "parameter", "displayName": "Management Enabled", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Whether management gathering is enabled" },
+    "readThrough": { "index": 5, "kind": "parameter", "displayName": "Read Through", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If read-through caching should be used" },
+    "statisticsEnabled": { "index": 6, "kind": "parameter", "displayName": "Statistics Enabled", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Whether statistics gathering is enabled" },
+    "storeByValue": { "index": 7, "kind": "parameter", "displayName": "Store By Value", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If cache should use store-by-value or store-by-reference semantics" },
+    "writeThrough": { "index": 8, "kind": "parameter", "displayName": "Write Through", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If write-through caching should be used" },
+    "filteredEvents": { "index": 9, "kind": "parameter", "displayName": "Filtered Events", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "CREATED", "UPDATED", "REMOVED", "EXPIRED" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Events a consumer should filter (multiple  [...]
+    "oldValueRequired": { "index": 10, "kind": "parameter", "displayName": "Old Value Required", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "if the old value is required for events" },
+    "synchronous": { "index": 11, "kind": "parameter", "displayName": "Synchronous", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "if the event listener should block the thread causing the event" },
+    "bridgeErrorHandler": { "index": 12, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming [...]
+    "eventFilters": { "index": 13, "kind": "parameter", "displayName": "Event Filters", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<javax.cache.event.CacheEntryEventFilter>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The CacheEntryEventFilter. If using eventFi [...]
+    "exceptionHandler": { "index": 14, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By de [...]
+    "exchangePattern": { "index": 15, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+    "action": { "index": 16, "kind": "parameter", "displayName": "Action", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "To configure using a cache operation by default. If an operation in the message header, then the operation from th [...]
+    "lazyStartProducer": { "index": 17, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...]
+    "cacheConfiguration": { "index": 18, "kind": "parameter", "displayName": "Cache Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.cache.configuration.Configuration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "A Configuration for the Cache" },
     "cacheLoaderFactory": { "index": 19, "kind": "parameter", "displayName": "Cache Loader Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.cache.configuration.Factory<javax.cache.integration.CacheLoader>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The CacheLoader factory" },
     "cacheWriterFactory": { "index": 20, "kind": "parameter", "displayName": "Cache Writer Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.cache.configuration.Factory<javax.cache.integration.CacheWriter>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The CacheWriter factory" },
     "createCacheIfNotExists": { "index": 21, "kind": "parameter", "displayName": "Create Cache If Not Exists", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Configure if a cache need to be created if it does exist or can' [...]
diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
index 1932fb506a5..6406ba99f0c 100644
--- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
+++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
@@ -34,6 +34,7 @@ import org.apache.camel.tooling.model.Kind;
 import org.apache.camel.tooling.model.LanguageModel;
 import org.apache.camel.tooling.model.MainModel;
 import org.apache.camel.tooling.model.OtherModel;
+import org.apache.camel.tooling.model.PojoBeanModel;
 import org.apache.camel.tooling.model.ReleaseModel;
 import org.apache.camel.tooling.model.TransformerModel;
 
@@ -217,6 +218,11 @@ public interface CamelCatalog {
      */
     List<String> findOtherNames();
 
+    /**
+     * Find all the pojo beans names from the Camel catalog
+     */
+    List<String> findBeansNames();
+
     /**
      * Find all the capability names from the Camel catalog
      */
@@ -242,6 +248,8 @@ public interface CamelCatalog {
                 return findOtherNames();
             case eip:
                 return findModelNames();
+            case bean:
+                return findBeansNames();
             default:
                 throw new IllegalArgumentException("Unexpected kind " + kind);
         }
@@ -586,6 +594,12 @@ public interface CamelCatalog {
      */
     EipModel eipModel(String name);
 
+    /**
+     * @param  name the FQN class name to look up
+     * @return      the requested Bean model or {@code null} in case it is not available in this {@link CamelCatalog}
+     */
+    PojoBeanModel pojoBeanModel(String name);
+
     /**
      * @return the requested main model or {@code null} in case it is not available in this {@link CamelCatalog}
      */
diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalogJSonSchemaResolver.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalogJSonSchemaResolver.java
index c5251125a2c..fb01ee50468 100644
--- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalogJSonSchemaResolver.java
+++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalogJSonSchemaResolver.java
@@ -138,6 +138,13 @@ public class CamelCatalogJSonSchemaResolver implements JSonSchemaResolver {
         return loadResourceFromVersionManager(file);
     }
 
+    @Override
+    public String getPojoBeanJSonSchema(String name) {
+        name = sanitizeFileName(name);
+        final String file = camelCatalog.getRuntimeProvider().getPojoBeanJSonSchemaDirectory() + "/" + name + EXTENSION;
+        return loadResourceFromVersionManager(file);
+    }
+
     String loadFromClasspath(final String className, final String fileName) {
         if (className != null) {
             String packageName = className.substring(0, className.lastIndexOf('.'));
diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
index 58fe3b1dbde..0c7d873df41 100644
--- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
+++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java
@@ -47,6 +47,7 @@ import org.apache.camel.tooling.model.Kind;
 import org.apache.camel.tooling.model.LanguageModel;
 import org.apache.camel.tooling.model.MainModel;
 import org.apache.camel.tooling.model.OtherModel;
+import org.apache.camel.tooling.model.PojoBeanModel;
 import org.apache.camel.tooling.model.ReleaseModel;
 import org.apache.camel.tooling.model.TransformerModel;
 import org.apache.camel.util.json.JsonArray;
@@ -89,6 +90,9 @@ public class DefaultCamelCatalog extends AbstractCachingCamelCatalog implements
     public static final String FIND_OTHER_LABELS = "findOtherLabels";
     public static final String LIST_OTHERS_AS_JSON = "listOthersAsJson";
 
+    public static final String FIND_BEAN_NAMES = "findBeanNames";
+    public static final String LIST_BEANS_AS_JSON = "listBeansAsJson";
+
     public static final String SUMMARY_AS_JSON = "summaryAsJson";
 
     private final VersionHelper version = new VersionHelper();
@@ -273,6 +277,11 @@ public class DefaultCamelCatalog extends AbstractCachingCamelCatalog implements
         return cache(FIND_OTHER_NAMES, runtimeProvider::findOtherNames);
     }
 
+    @Override
+    public List<String> findBeansNames() {
+        return cache(FIND_BEAN_NAMES, runtimeProvider::findBeansNames);
+    }
+
     @Override
     public List<String> findModelNames(String filter) {
         // should not cache when filter parameter can by any kind of value
@@ -342,6 +351,11 @@ public class DefaultCamelCatalog extends AbstractCachingCamelCatalog implements
         return cache("eip-model-" + name, name, super::eipModel);
     }
 
+    @Override
+    public PojoBeanModel pojoBeanModel(String name) {
+        return cache("pojo-bean-model-" + name, name, super::pojoBeanModel);
+    }
+
     @Override
     public String componentJSonSchema(String name) {
         return cache("component-" + name, name, super::componentJSonSchema);
diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultRuntimeProvider.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultRuntimeProvider.java
index 9abb9e93ff0..f80763ce3b2 100644
--- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultRuntimeProvider.java
+++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/DefaultRuntimeProvider.java
@@ -34,6 +34,7 @@ public class DefaultRuntimeProvider implements RuntimeProvider {
     private static final String TRANSFORMER_DIR = "org/apache/camel/catalog/transformers";
     private static final String CONSOLE_DIR = "org/apache/camel/catalog/dev-consoles";
     private static final String OTHER_DIR = "org/apache/camel/catalog/others";
+    private static final String BEANS_DIR = "org/apache/camel/catalog/beans";
     private static final String COMPONENTS_CATALOG = "org/apache/camel/catalog/components.properties";
     private static final String DATA_FORMATS_CATALOG = "org/apache/camel/catalog/dataformats.properties";
     private static final String LANGUAGE_CATALOG = "org/apache/camel/catalog/languages.properties";
@@ -41,6 +42,7 @@ public class DefaultRuntimeProvider implements RuntimeProvider {
     private static final String CONSOLE_CATALOG = "org/apache/camel/catalog/dev-consoles.properties";
     private static final String OTHER_CATALOG = "org/apache/camel/catalog/others.properties";
     private static final String CAPABILITIES_CATALOG = "org/apache/camel/catalog/capabilities.properties";
+    private static final String BEANS_CATALOG = "org/apache/camel/catalog/beans.properties";
 
     private CamelCatalog camelCatalog;
 
@@ -106,6 +108,11 @@ public class DefaultRuntimeProvider implements RuntimeProvider {
         return OTHER_DIR;
     }
 
+    @Override
+    public String getPojoBeanJSonSchemaDirectory() {
+        return BEANS_DIR;
+    }
+
     protected String getComponentsCatalog() {
         return COMPONENTS_CATALOG;
     }
@@ -134,6 +141,10 @@ public class DefaultRuntimeProvider implements RuntimeProvider {
         return CAPABILITIES_CATALOG;
     }
 
+    protected String getBeansCatalog() {
+        return BEANS_CATALOG;
+    }
+
     @Override
     public List<String> findComponentNames() {
         return find(getComponentsCatalog());
@@ -164,6 +175,11 @@ public class DefaultRuntimeProvider implements RuntimeProvider {
         return find(getOtherCatalog());
     }
 
+    @Override
+    public List<String> findBeansNames() {
+        return find(getBeansCatalog());
+    }
+
     @SuppressWarnings({ "unchecked", "rawtypes" })
     @Override
     public Map<String, String> findCapabilities() {
diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/RuntimeProvider.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/RuntimeProvider.java
index ef3841f856c..5d65d45207c 100644
--- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/RuntimeProvider.java
+++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/RuntimeProvider.java
@@ -81,6 +81,11 @@ public interface RuntimeProvider {
      */
     String getOtherJSonSchemaDirectory();
 
+    /**
+     * Gets the directory where the pojo bean json files are stored in the catalog JAR file
+     */
+    String getPojoBeanJSonSchemaDirectory();
+
     /**
      * Find all the component names from the Camel catalog supported by the provider
      */
@@ -111,6 +116,11 @@ public interface RuntimeProvider {
      */
     List<String> findOtherNames();
 
+    /**
+     * Find all the pojo beans names from the Camel catalog supported by the provider
+     */
+    List<String> findBeansNames();
+
     /**
      * Find all the capabilities from the Camel catalog supported by the provider
      */
diff --git a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
index 997851ebd98..05740bbacb7 100644
--- a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
+++ b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
@@ -34,6 +34,7 @@ import org.apache.camel.tooling.model.DataFormatModel;
 import org.apache.camel.tooling.model.EntityRef;
 import org.apache.camel.tooling.model.Kind;
 import org.apache.camel.tooling.model.LanguageModel;
+import org.apache.camel.tooling.model.PojoBeanModel;
 import org.apache.camel.tooling.model.ReleaseModel;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -1632,4 +1633,24 @@ public class CamelCatalogTest {
         Optional<EntityRef> ref2 = catalog.findCapabilityRef("not-implemented");
         Assertions.assertFalse(ref2.isPresent());
     }
+
+    @Test
+    public void testFindPojoBeanNames() {
+        List<String> names = catalog.findBeansNames();
+
+        assertTrue(names.contains("GroupedBodyAggregationStrategy"));
+        assertTrue(names.contains("ZipAggregationStrategy"));
+    }
+
+    @Test
+    public void testPojoBeanModel() {
+        PojoBeanModel model = catalog.pojoBeanModel("ZipAggregationStrategy");
+        assertNotNull(model);
+
+        assertEquals("bean", model.getKind());
+        assertEquals("ZipAggregationStrategy", model.getName());
+        assertEquals("org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy", model.getJavaType());
+        assertEquals(6, model.getOptions().size());
+    }
+
 }
diff --git a/components/camel-caffeine/src/generated/java/org/apache/camel/component/caffeine/processor/aggregate/CaffeineAggregationRepositoryConfigurer.java b/components/camel-caffeine/src/generated/java/org/apache/camel/component/caffeine/processor/aggregate/CaffeineAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..70defcf6cc4
--- /dev/null
+++ b/components/camel-caffeine/src/generated/java/org/apache/camel/component/caffeine/processor/aggregate/CaffeineAggregationRepositoryConfigurer.java
@@ -0,0 +1,73 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.caffeine.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class CaffeineAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository target = (org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository target = (org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-caffeine/src/generated/java/org/apache/camel/component/caffeine/processor/idempotent/CaffeineIdempotentRepositoryConfigurer.java b/components/camel-caffeine/src/generated/java/org/apache/camel/component/caffeine/processor/idempotent/CaffeineIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..fe44c3d1e8e
--- /dev/null
+++ b/components/camel-caffeine/src/generated/java/org/apache/camel/component/caffeine/processor/idempotent/CaffeineIdempotentRepositoryConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.caffeine.processor.idempotent;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class CaffeineIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository target = (org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": target.setCacheName(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository target = (org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": return target.getCacheName();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..a892ad7ec3f
--- /dev/null
+++ b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=CaffeineAggregationRepository CaffeineIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-caffeine
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Caffeine
+projectDescription=Camel Caffeine support
diff --git a/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean/CaffeineAggregationRepository.json b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean/CaffeineAggregationRepository.json
new file mode 100644
index 00000000000..14de19f8f81
--- /dev/null
+++ b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean/CaffeineAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "CaffeineAggregationRepository",
+    "javaType": "org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Caffeine Aggregation Repository",
+    "description": "Aggregation repository that uses Caffeine Cache to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-caffeine",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "useRecovery": { "index": 0, "kind": "property", "displayName": "Use Recovery", "required": false, "type": "object", "javaType": "org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "true", "description": "Whether or not recovery is enabled" }, "deadLetterUri": { "index": 1, "kind": "property", "displayName": "Dead Letter Uri", "required": false, "type": "obje [...]
+  }
+}
+
diff --git a/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean/CaffeineIdempotentRepository.json b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean/CaffeineIdempotentRepository.json
new file mode 100644
index 00000000000..dfc7548e400
--- /dev/null
+++ b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/bean/CaffeineIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "CaffeineIdempotentRepository",
+    "javaType": "org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Caffeine Idempotent Repository",
+    "description": "Idempotent repository that uses Caffiene cache to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-caffeine",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": false, "type": "object", "javaType": "org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "CaffeineIdempotentRepository", "description": "Name of cache" } }
+  }
+}
+
diff --git a/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository
new file mode 100644
index 00000000000..31b85d95531
--- /dev/null
+++ b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.caffeine.processor.aggregate.CaffeineAggregationRepositoryConfigurer
diff --git a/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository
new file mode 100644
index 00000000000..030456f2470
--- /dev/null
+++ b/components/camel-caffeine/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.caffeine.processor.idempotent.CaffeineIdempotentRepositoryConfigurer
diff --git a/components/camel-caffeine/src/main/java/org/apache/camel/component/caffeine/processor/aggregate/CaffeineAggregationRepository.java b/components/camel-caffeine/src/main/java/org/apache/camel/component/caffeine/processor/aggregate/CaffeineAggregationRepository.java
index 23cca1b55ac..3c256a53b11 100644
--- a/components/camel-caffeine/src/main/java/org/apache/camel/component/caffeine/processor/aggregate/CaffeineAggregationRepository.java
+++ b/components/camel-caffeine/src/main/java/org/apache/camel/component/caffeine/processor/aggregate/CaffeineAggregationRepository.java
@@ -24,6 +24,9 @@ import com.github.benmanes.caffeine.cache.Cache;
 import com.github.benmanes.caffeine.cache.Caffeine;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.DefaultExchange;
 import org.apache.camel.support.DefaultExchangeHolder;
@@ -31,18 +34,31 @@ import org.apache.camel.support.service.ServiceSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses Caffeine Cache to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
+@ManagedResource(description = "Caffeine based aggregation repository")
 public class CaffeineAggregationRepository extends ServiceSupport implements RecoverableAggregationRepository {
 
     private static final Logger LOG = LoggerFactory.getLogger(CaffeineAggregationRepository.class);
 
     private CamelContext camelContext;
     private Cache<String, DefaultExchangeHolder> cache;
-    private boolean allowSerializedHeaders;
 
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
     private boolean useRecovery = true;
-    private String deadLetterChannel;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
+    private String deadLetterUri;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
     private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.",
+              defaultValue = "3")
     private int maximumRedeliveries = 3;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
+    private boolean allowSerializedHeaders;
 
     public CamelContext getCamelContext() {
         return camelContext;
@@ -70,12 +86,12 @@ public class CaffeineAggregationRepository extends ServiceSupport implements Rec
 
     @Override
     public void setDeadLetterUri(String deadLetterUri) {
-        this.deadLetterChannel = deadLetterUri;
+        this.deadLetterUri = deadLetterUri;
     }
 
     @Override
     public String getDeadLetterUri() {
-        return deadLetterChannel;
+        return deadLetterUri;
     }
 
     @Override
@@ -88,23 +104,10 @@ public class CaffeineAggregationRepository extends ServiceSupport implements Rec
         this.useRecovery = useRecovery;
     }
 
-    public String getDeadLetterChannel() {
-        return deadLetterChannel;
-    }
-
-    public void setDeadLetterChannel(String deadLetterChannel) {
-        this.deadLetterChannel = deadLetterChannel;
-    }
-
     public long getRecoveryInterval() {
         return recoveryInterval;
     }
 
-    @Override
-    public long getRecoveryIntervalInMillis() {
-        return recoveryInterval;
-    }
-
     @Override
     public void setRecoveryInterval(long recoveryInterval) {
         this.recoveryInterval = recoveryInterval;
@@ -192,6 +195,7 @@ public class CaffeineAggregationRepository extends ServiceSupport implements Rec
 
     @Override
     protected void doStop() throws Exception {
+        // noop
     }
 
     public static Exchange unmarshallExchange(CamelContext camelContext, DefaultExchangeHolder holder) {
diff --git a/components/camel-caffeine/src/main/java/org/apache/camel/component/caffeine/processor/idempotent/CaffeineIdempotentRepository.java b/components/camel-caffeine/src/main/java/org/apache/camel/component/caffeine/processor/idempotent/CaffeineIdempotentRepository.java
index 0b21eaa698b..46fba2c3155 100644
--- a/components/camel-caffeine/src/main/java/org/apache/camel/component/caffeine/processor/idempotent/CaffeineIdempotentRepository.java
+++ b/components/camel-caffeine/src/main/java/org/apache/camel/component/caffeine/processor/idempotent/CaffeineIdempotentRepository.java
@@ -21,15 +21,23 @@ import com.github.benmanes.caffeine.cache.Caffeine;
 import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.service.ServiceSupport;
 
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses Caffiene cache to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 @ManagedResource(description = "Caffeine based message id repository")
 public class CaffeineIdempotentRepository extends ServiceSupport implements IdempotentRepository {
 
-    private String cacheName;
     private Cache<String, Boolean> cache;
 
+    @Metadata(description = "Name of cache", defaultValue = "CaffeineIdempotentRepository")
+    private String cacheName;
+
     public CaffeineIdempotentRepository() {
         this(CaffeineIdempotentRepository.class.getSimpleName());
     }
@@ -38,6 +46,10 @@ public class CaffeineIdempotentRepository extends ServiceSupport implements Idem
         this.cacheName = repositoryName;
     }
 
+    public void setCacheName(String cacheName) {
+        this.cacheName = cacheName;
+    }
+
     @ManagedAttribute(description = "The processor name")
     public String getCacheName() {
         return cacheName;
@@ -86,11 +98,12 @@ public class CaffeineIdempotentRepository extends ServiceSupport implements Idem
         }
     }
 
-    protected Cache getCache() {
-        return this.cache;
-    }
-
     @Override
     protected void doStop() throws Exception {
+        // noop
+    }
+
+    protected Cache getCache() {
+        return this.cache;
     }
 }
diff --git a/components/camel-cassandraql/src/generated/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepositoryConfigurer.java b/components/camel-cassandraql/src/generated/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..ffe91b8bb76
--- /dev/null
+++ b/components/camel-cassandraql/src/generated/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepositoryConfigurer.java
@@ -0,0 +1,127 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate.cassandra;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class CassandraAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository target = (org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "exchangecolumn":
+        case "ExchangeColumn": target.setExchangeColumn(property(camelContext, java.lang.String.class, value)); return true;
+        case "exchangeidcolumn":
+        case "ExchangeIdColumn": target.setExchangeIdColumn(property(camelContext, java.lang.String.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "pkcolumns":
+        case "PKColumns": target.setPKColumns(property(camelContext, java.lang.String[].class, value)); return true;
+        case "prefixpkvalues":
+        case "PrefixPKValues": target.setPrefixPKValues(property(camelContext, java.lang.Object[].class, value)); return true;
+        case "readconsistencylevel":
+        case "ReadConsistencyLevel": target.setReadConsistencyLevel(property(camelContext, com.datastax.oss.driver.api.core.ConsistencyLevel.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "session":
+        case "Session": target.setSession(property(camelContext, com.datastax.oss.driver.api.core.CqlSession.class, value)); return true;
+        case "table":
+        case "Table": target.setTable(property(camelContext, java.lang.String.class, value)); return true;
+        case "ttl":
+        case "Ttl": target.setTtl(property(camelContext, java.lang.Integer.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        case "writeconsistencylevel":
+        case "WriteConsistencyLevel": target.setWriteConsistencyLevel(property(camelContext, com.datastax.oss.driver.api.core.ConsistencyLevel.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "exchangecolumn":
+        case "ExchangeColumn": return java.lang.String.class;
+        case "exchangeidcolumn":
+        case "ExchangeIdColumn": return java.lang.String.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "pkcolumns":
+        case "PKColumns": return java.lang.String[].class;
+        case "prefixpkvalues":
+        case "PrefixPKValues": return java.lang.Object[].class;
+        case "readconsistencylevel":
+        case "ReadConsistencyLevel": return com.datastax.oss.driver.api.core.ConsistencyLevel.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "session":
+        case "Session": return com.datastax.oss.driver.api.core.CqlSession.class;
+        case "table":
+        case "Table": return java.lang.String.class;
+        case "ttl":
+        case "Ttl": return java.lang.Integer.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        case "writeconsistencylevel":
+        case "WriteConsistencyLevel": return com.datastax.oss.driver.api.core.ConsistencyLevel.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository target = (org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "exchangecolumn":
+        case "ExchangeColumn": return target.getExchangeColumn();
+        case "exchangeidcolumn":
+        case "ExchangeIdColumn": return target.getExchangeIdColumn();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "pkcolumns":
+        case "PKColumns": return target.getPKColumns();
+        case "prefixpkvalues":
+        case "PrefixPKValues": return target.getPrefixPKValues();
+        case "readconsistencylevel":
+        case "ReadConsistencyLevel": return target.getReadConsistencyLevel();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "session":
+        case "Session": return target.getSession();
+        case "table":
+        case "Table": return target.getTable();
+        case "ttl":
+        case "Ttl": return target.getTtl();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        case "writeconsistencylevel":
+        case "WriteConsistencyLevel": return target.getWriteConsistencyLevel();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-cassandraql/src/generated/java/org/apache/camel/processor/idempotent/cassandra/CassandraIdempotentRepositoryConfigurer.java b/components/camel-cassandraql/src/generated/java/org/apache/camel/processor/idempotent/cassandra/CassandraIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..96bc8b2f760
--- /dev/null
+++ b/components/camel-cassandraql/src/generated/java/org/apache/camel/processor/idempotent/cassandra/CassandraIdempotentRepositoryConfigurer.java
@@ -0,0 +1,85 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.idempotent.cassandra;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class CassandraIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository target = (org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "pkcolumns":
+        case "PKColumns": target.setPKColumns(property(camelContext, java.lang.String[].class, value)); return true;
+        case "prefixpkvalues":
+        case "PrefixPKValues": target.setPrefixPKValues(property(camelContext, java.lang.String[].class, value)); return true;
+        case "readconsistencylevel":
+        case "ReadConsistencyLevel": target.setReadConsistencyLevel(property(camelContext, com.datastax.oss.driver.api.core.ConsistencyLevel.class, value)); return true;
+        case "session":
+        case "Session": target.setSession(property(camelContext, com.datastax.oss.driver.api.core.CqlSession.class, value)); return true;
+        case "table":
+        case "Table": target.setTable(property(camelContext, java.lang.String.class, value)); return true;
+        case "ttl":
+        case "Ttl": target.setTtl(property(camelContext, java.lang.Integer.class, value)); return true;
+        case "writeconsistencylevel":
+        case "WriteConsistencyLevel": target.setWriteConsistencyLevel(property(camelContext, com.datastax.oss.driver.api.core.ConsistencyLevel.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "pkcolumns":
+        case "PKColumns": return java.lang.String[].class;
+        case "prefixpkvalues":
+        case "PrefixPKValues": return java.lang.String[].class;
+        case "readconsistencylevel":
+        case "ReadConsistencyLevel": return com.datastax.oss.driver.api.core.ConsistencyLevel.class;
+        case "session":
+        case "Session": return com.datastax.oss.driver.api.core.CqlSession.class;
+        case "table":
+        case "Table": return java.lang.String.class;
+        case "ttl":
+        case "Ttl": return java.lang.Integer.class;
+        case "writeconsistencylevel":
+        case "WriteConsistencyLevel": return com.datastax.oss.driver.api.core.ConsistencyLevel.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository target = (org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "pkcolumns":
+        case "PKColumns": return target.getPKColumns();
+        case "prefixpkvalues":
+        case "PrefixPKValues": return target.getPrefixPKValues();
+        case "readconsistencylevel":
+        case "ReadConsistencyLevel": return target.getReadConsistencyLevel();
+        case "session":
+        case "Session": return target.getSession();
+        case "table":
+        case "Table": return target.getTable();
+        case "ttl":
+        case "Ttl": return target.getTtl();
+        case "writeconsistencylevel":
+        case "WriteConsistencyLevel": return target.getWriteConsistencyLevel();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..da91b64f53b
--- /dev/null
+++ b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=CassandraAggregationRepository CassandraIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-cassandraql
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Cassandra CQL
+projectDescription=Cassandra CQL3 support
diff --git a/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean/CassandraAggregationRepository.json b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean/CassandraAggregationRepository.json
new file mode 100644
index 00000000000..c05e5b56162
--- /dev/null
+++ b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean/CassandraAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "CassandraAggregationRepository",
+    "javaType": "org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Cassandra Aggregation Repository",
+    "description": "Aggregation repository that uses Cassandra table to store exchanges. Advice: use LeveledCompaction for this table and tune read\/write consistency levels.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-cassandraql",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "sessionHolder": { "index": 0, "kind": "property", "displayName": "Session Holder", "required": true, "type": "object", "javaType": "org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Cassandra session" }, "table": { "index": 1, "kind": "property", "displayName": "Table", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.cassandra [...]
+  }
+}
+
diff --git a/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean/CassandraIdempotentRepository.json b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean/CassandraIdempotentRepository.json
new file mode 100644
index 00000000000..78269b7e649
--- /dev/null
+++ b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/bean/CassandraIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "CassandraIdempotentRepository",
+    "javaType": "org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Cassandra Idempotent Repository",
+    "description": "Idempotent repository that uses Cassandra table to store message ids. Advice: use LeveledCompaction for this table and tune read\/write consistency levels.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-cassandraql",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "session": { "index": 0, "kind": "property", "displayName": "Session", "required": true, "type": "object", "javaType": "org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Cassandra session" }, "table": { "index": 1, "kind": "property", "displayName": "Table", "required": false, "type": "object", "javaType": "org.apache.camel.processor.idempotent.cassandra.CassandraId [...]
+  }
+}
+
diff --git a/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository
new file mode 100644
index 00000000000..c136547de65
--- /dev/null
+++ b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.cassandra.CassandraAggregationRepositoryConfigurer
diff --git a/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository
new file mode 100644
index 00000000000..53576393003
--- /dev/null
+++ b/components/camel-cassandraql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.idempotent.cassandra.CassandraIdempotentRepositoryConfigurer
diff --git a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepository.java b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepository.java
index b64653a96f1..2c0febfac95 100644
--- a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepository.java
+++ b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/CassandraAggregationRepository.java
@@ -34,6 +34,8 @@ import com.datastax.oss.driver.api.querybuilder.select.Select;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.spi.AggregationRepository;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.utils.cassandra.CassandraSessionHolder;
@@ -53,50 +55,39 @@ import static org.apache.camel.utils.cassandra.CassandraUtils.generateSelect;
  * LeveledCompaction for this table and tune read/write consistency levels. Warning: Cassandra is not the best tool for
  * queuing use cases See: http://www.datastax.com/dev/blog/cassandra-anti-patterns-queues-and-queue-like-datasets
  */
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses Cassandra table to store exchanges."
+                        + " Advice: use LeveledCompaction for this table and tune read/write consistency levels.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class CassandraAggregationRepository extends ServiceSupport implements RecoverableAggregationRepository {
-    /**
-     * Logger
-     */
+
     private static final Logger LOGGER = LoggerFactory.getLogger(CassandraAggregationRepository.class);
-    /**
-     * Session holder
-     */
+
+    private final CassandraCamelCodec exchangeCodec = new CassandraCamelCodec();
+
+    @Metadata(description = "Cassandra session", required = true)
     private CassandraSessionHolder sessionHolder;
-    /**
-     * Table name
-     */
+    @Metadata(description = "The table name for storing the data", defaultValue = "CAMEL_AGGREGATION")
     private String table = "CAMEL_AGGREGATION";
-    /**
-     * Exchange Id column name
-     */
+    @Metadata(description = "Column name for Exchange ID", defaultValue = "EXCHANGE_ID")
     private String exchangeIdColumn = "EXCHANGE_ID";
-    /**
-     * Exchange column name
-     */
+    @Metadata(description = "Column name for Exchange", defaultValue = "EXCHANGE")
     private String exchangeColumn = "EXCHANGE";
-    /**
-     * Values used as primary key prefix
-     */
+    @Metadata(description = "Values used as primary key prefix. Multiple values can be separated by comma.",
+              displayName = "Prefix Primary Key Values", javaType = "java.lang.String")
     private Object[] prefixPKValues = new Object[0];
-    /**
-     * Primary key columns
-     */
+    @Metadata(description = "Primary key columns. Multiple values can be separated by comma.",
+              displayName = "Primary Key Columns",
+              javaType = "java.lang.String", defaultValue = "KEY")
     private String[] pkColumns = { "KEY" };
-    /**
-     * Exchange marshaller/unmarshaller
-     */
-    private final CassandraCamelCodec exchangeCodec = new CassandraCamelCodec();
-    /**
-     * Time to live in seconds used for inserts
-     */
+    @Metadata(description = "Time to live in seconds used for inserts", displayName = "Time to Live")
     private Integer ttl;
-    /**
-     * Writeconsistency level
-     */
+    @Metadata(description = "Write consistency level",
+              enums = "ANY,ONE,TWO,THREE,QUORUM,ALL,LOCAL_ONE,LOCAL_QUORUM,EACH_QUORUM,SERIAL,LOCAL_SERIAL")
     private ConsistencyLevel writeConsistencyLevel;
-    /**
-     * Read consistency level
-     */
+    @Metadata(description = "Read consistency level",
+              enums = "ANY,ONE,TWO,THREE,QUORUM,ALL,LOCAL_ONE,LOCAL_QUORUM,EACH_QUORUM,SERIAL,LOCAL_SERIAL")
     private ConsistencyLevel readConsistencyLevel;
 
     private PreparedStatement insertStatement;
@@ -111,14 +102,17 @@ public class CassandraAggregationRepository extends ServiceSupport implements Re
      */
     private PreparedStatement deleteIfIdStatement;
 
-    private long recoveryIntervalInMillis = 5000;
-
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
+    private long recoveryInterval = 5000;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
     private boolean useRecovery = true;
-
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
     private String deadLetterUri;
-
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.")
     private int maximumRedeliveries;
-
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
     private boolean allowSerializedHeaders;
 
     /**
@@ -286,9 +280,9 @@ public class CassandraAggregationRepository extends ServiceSupport implements Re
                 // Id
                 // columns
                 pkColumns, pkColumns.length - 1); // Where
-                                                 // fixed
-                                                 // PK
-                                                 // columns
+        // fixed
+        // PK
+        // columns
         SimpleStatement statement = applyConsistencyLevel(select.build(), readConsistencyLevel);
         LOGGER.debug("Generated Select keys {}", statement);
         selectKeyIdStatement = getSession().prepare(statement);
@@ -421,23 +415,18 @@ public class CassandraAggregationRepository extends ServiceSupport implements Re
         this.ttl = ttl;
     }
 
-    @Override
-    public long getRecoveryIntervalInMillis() {
-        return recoveryIntervalInMillis;
-    }
-
-    public void setRecoveryIntervalInMillis(long recoveryIntervalInMillis) {
-        this.recoveryIntervalInMillis = recoveryIntervalInMillis;
+    public long getRecoveryInterval() {
+        return recoveryInterval;
     }
 
     @Override
     public void setRecoveryInterval(long interval, TimeUnit timeUnit) {
-        this.recoveryIntervalInMillis = timeUnit.toMillis(interval);
+        this.recoveryInterval = timeUnit.toMillis(interval);
     }
 
     @Override
-    public void setRecoveryInterval(long recoveryIntervalInMillis) {
-        this.recoveryIntervalInMillis = recoveryIntervalInMillis;
+    public void setRecoveryInterval(long recoveryInterval) {
+        this.recoveryInterval = recoveryInterval;
     }
 
     @Override
diff --git a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/NamedCassandraAggregationRepository.java b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/NamedCassandraAggregationRepository.java
index f2861a2a5a1..b44f20e61ac 100644
--- a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/NamedCassandraAggregationRepository.java
+++ b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/aggregate/cassandra/NamedCassandraAggregationRepository.java
@@ -23,6 +23,7 @@ import com.datastax.oss.driver.api.core.CqlSession;
  * key) and key (clustering key).
  */
 public class NamedCassandraAggregationRepository extends CassandraAggregationRepository {
+
     public NamedCassandraAggregationRepository() {
         setPKColumns("NAME", "KEY");
         setName("DEFAULT");
diff --git a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/idempotent/cassandra/CassandraIdempotentRepository.java b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/idempotent/cassandra/CassandraIdempotentRepository.java
index 6561414cff9..c66d4d7a8dd 100644
--- a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/idempotent/cassandra/CassandraIdempotentRepository.java
+++ b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/idempotent/cassandra/CassandraIdempotentRepository.java
@@ -26,8 +26,11 @@ import com.datastax.oss.driver.api.querybuilder.delete.Delete;
 import com.datastax.oss.driver.api.querybuilder.insert.Insert;
 import com.datastax.oss.driver.api.querybuilder.select.Select;
 import com.datastax.oss.driver.api.querybuilder.truncate.Truncate;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.utils.cassandra.CassandraSessionHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,39 +47,35 @@ import static org.apache.camel.utils.cassandra.CassandraUtils.generateTruncate;
  * LeveledCompaction for this table and tune read/write consistency levels. Warning: Cassandra is not the best tool for
  * queuing use cases See http://www.datastax.com/dev/blog/cassandra-anti-patterns-queues-and-queue-like-datasets
  */
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses Cassandra table to store message ids."
+                        + " Advice: use LeveledCompaction for this table and tune read/write consistency levels.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 public class CassandraIdempotentRepository extends ServiceSupport implements IdempotentRepository {
-    /**
-     * Logger
-     */
+
     private static final Logger LOGGER = LoggerFactory.getLogger(CassandraIdempotentRepository.class);
-    /**
-     * Session holder
-     */
-    private CassandraSessionHolder sessionHolder;
-    /**
-     * Table name
-     */
+
+    @Metadata(description = "Cassandra session", required = true)
+    private CassandraSessionHolder session;
+    @Metadata(description = "The table name for storing the data", defaultValue = "CAMEL_IDEMPOTENT")
     private String table = "CAMEL_IDEMPOTENT";
-    /**
-     * Values used as primary key prefix
-     */
+    @Metadata(description = "Values used as primary key prefix. Multiple values can be separated by comma.",
+              displayName = "Prefix Primary Key Values", javaType = "java.lang.String")
     private String[] prefixPKValues = new String[0];
-    /**
-     * Primary key columns
-     */
+    @Metadata(description = "Primary key columns. Multiple values can be separated by comma.",
+              displayName = "Primary Key Columns",
+              javaType = "java.lang.String", defaultValue = "KEY")
     private String[] pkColumns = { "KEY" };
-    /**
-     * Time to live in seconds used for inserts
-     */
+    @Metadata(description = "Time to live in seconds used for inserts", displayName = "Time to Live")
     private Integer ttl;
-    /**
-     * Write consistency level
-     */
+    @Metadata(description = "Write consistency level",
+              enums = "ANY,ONE,TWO,THREE,QUORUM,ALL,LOCAL_ONE,LOCAL_QUORUM,EACH_QUORUM,SERIAL,LOCAL_SERIAL")
     private ConsistencyLevel writeConsistencyLevel;
-    /**
-     * Read consistency level
-     */
+    @Metadata(description = "Read consistency level",
+              enums = "ANY,ONE,TWO,THREE,QUORUM,ALL,LOCAL_ONE,LOCAL_QUORUM,EACH_QUORUM,SERIAL,LOCAL_SERIAL")
     private ConsistencyLevel readConsistencyLevel;
+
     private PreparedStatement insertStatement;
     private PreparedStatement selectStatement;
     private PreparedStatement deleteStatement;
@@ -86,7 +85,7 @@ public class CassandraIdempotentRepository extends ServiceSupport implements Ide
     }
 
     public CassandraIdempotentRepository(CqlSession session) {
-        this.sessionHolder = new CassandraSessionHolder(session);
+        this.session = new CassandraSessionHolder(session);
     }
 
     private boolean isKey(ResultSet resultSet) {
@@ -113,7 +112,8 @@ public class CassandraIdempotentRepository extends ServiceSupport implements Ide
 
     @Override
     protected void doStart() throws Exception {
-        sessionHolder.start();
+        ObjectHelper.notNull(session, "session", this);
+        session.start();
         initInsertStatement();
         initSelectStatement();
         initDeleteStatement();
@@ -122,7 +122,9 @@ public class CassandraIdempotentRepository extends ServiceSupport implements Ide
 
     @Override
     protected void doStop() throws Exception {
-        sessionHolder.stop();
+        if (session != null) {
+            session.stop();
+        }
     }
     // -------------------------------------------------------------------------
     // Add key to repository
@@ -200,11 +202,11 @@ public class CassandraIdempotentRepository extends ServiceSupport implements Ide
     // Getters & Setters
 
     public CqlSession getSession() {
-        return sessionHolder.getSession();
+        return session.getSession();
     }
 
     public void setSession(CqlSession session) {
-        this.sessionHolder = new CassandraSessionHolder(session);
+        this.session = new CassandraSessionHolder(session);
     }
 
     public String getTable() {
@@ -223,6 +225,10 @@ public class CassandraIdempotentRepository extends ServiceSupport implements Ide
         this.pkColumns = pkColumns;
     }
 
+    public void setPKColumns(String value) {
+        this.pkColumns = value.split(",");
+    }
+
     public Integer getTtl() {
         return ttl;
     }
@@ -255,4 +261,8 @@ public class CassandraIdempotentRepository extends ServiceSupport implements Ide
         this.prefixPKValues = prefixPKValues;
     }
 
+    public void setPrefixPKValues(String values) {
+        this.prefixPKValues = values.split(",");
+    }
+
 }
diff --git a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/idempotent/cassandra/NamedCassandraIdempotentRepository.java b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/idempotent/cassandra/NamedCassandraIdempotentRepository.java
index e58f3175e7c..451c1e348b5 100644
--- a/components/camel-cassandraql/src/main/java/org/apache/camel/processor/idempotent/cassandra/NamedCassandraIdempotentRepository.java
+++ b/components/camel-cassandraql/src/main/java/org/apache/camel/processor/idempotent/cassandra/NamedCassandraIdempotentRepository.java
@@ -23,6 +23,7 @@ import com.datastax.oss.driver.api.core.CqlSession;
  * and key (clustering key).
  */
 public class NamedCassandraIdempotentRepository extends CassandraIdempotentRepository {
+
     public NamedCassandraIdempotentRepository() {
         setPKColumns("NAME", "KEY");
         setName("DEFAULT");
diff --git a/components/camel-ehcache/src/generated/java/org/apache/camel/component/ehcache/processor/aggregate/EhcacheAggregationRepositoryConfigurer.java b/components/camel-ehcache/src/generated/java/org/apache/camel/component/ehcache/processor/aggregate/EhcacheAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..34192f864aa
--- /dev/null
+++ b/components/camel-ehcache/src/generated/java/org/apache/camel/component/ehcache/processor/aggregate/EhcacheAggregationRepositoryConfigurer.java
@@ -0,0 +1,79 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.ehcache.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class EhcacheAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository target = (org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "cachename":
+        case "CacheName": target.setCacheName(property(camelContext, java.lang.String.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "cachename":
+        case "CacheName": return java.lang.String.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository target = (org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "cachename":
+        case "CacheName": return target.getCacheName();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-ehcache/src/generated/java/org/apache/camel/component/ehcache/processor/idempotent/EhcacheIdempotentRepositoryConfigurer.java b/components/camel-ehcache/src/generated/java/org/apache/camel/component/ehcache/processor/idempotent/EhcacheIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..62d363285a2
--- /dev/null
+++ b/components/camel-ehcache/src/generated/java/org/apache/camel/component/ehcache/processor/idempotent/EhcacheIdempotentRepositoryConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.ehcache.processor.idempotent;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class EhcacheIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository target = (org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": target.setCacheName(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository target = (org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": return target.getCacheName();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..52e8fc1c7ca
--- /dev/null
+++ b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=EhcacheAggregationRepository EhcacheIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-ehcache
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Ehcache
+projectDescription=Camel Ehcache support
diff --git a/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean/EhcacheAggregationRepository.json b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean/EhcacheAggregationRepository.json
new file mode 100644
index 00000000000..eed304ee999
--- /dev/null
+++ b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean/EhcacheAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "EhcacheAggregationRepository",
+    "javaType": "org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Ehcache Aggregation Repository",
+    "description": "Aggregation repository that uses Caffeine Cache to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-ehcache",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "allowSerializedHeaders": { "index": 1, "kind": "property", "displayName": "Allow Serialized Headers", "label": "advanced", "required": false, "type": "object", "javaTyp [...]
+  }
+}
+
diff --git a/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean/EhcacheIdempotentRepository.json b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean/EhcacheIdempotentRepository.json
new file mode 100644
index 00000000000..8cc0d729756
--- /dev/null
+++ b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/bean/EhcacheIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "EhcacheIdempotentRepository",
+    "javaType": "org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Ehcache Idempotent Repository",
+    "description": "Idempotent repository that uses EHCache cache to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-ehcache",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": false, "type": "object", "javaType": "org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "EhcacheIdempotentRepository", "description": "Name of cache" } }
+  }
+}
+
diff --git a/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository
new file mode 100644
index 00000000000..6adb8bb4e53
--- /dev/null
+++ b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.ehcache.processor.aggregate.EhcacheAggregationRepositoryConfigurer
diff --git a/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository
new file mode 100644
index 00000000000..b4f6f23adf8
--- /dev/null
+++ b/components/camel-ehcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.ehcache.processor.idempotent.EhcacheIdempotentRepositoryConfigurer
diff --git a/components/camel-ehcache/src/main/java/org/apache/camel/component/ehcache/processor/aggregate/EhcacheAggregationRepository.java b/components/camel-ehcache/src/main/java/org/apache/camel/component/ehcache/processor/aggregate/EhcacheAggregationRepository.java
index 81e9a47cdec..8fb1a80c819 100644
--- a/components/camel-ehcache/src/main/java/org/apache/camel/component/ehcache/processor/aggregate/EhcacheAggregationRepository.java
+++ b/components/camel-ehcache/src/main/java/org/apache/camel/component/ehcache/processor/aggregate/EhcacheAggregationRepository.java
@@ -23,6 +23,9 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.DefaultExchange;
 import org.apache.camel.support.DefaultExchangeHolder;
@@ -33,19 +36,33 @@ import org.ehcache.CacheManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses Caffeine Cache to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
+@ManagedResource(description = "EHCache based aggregation repository")
 public class EhcacheAggregationRepository extends ServiceSupport implements RecoverableAggregationRepository {
 
     private static final Logger LOG = LoggerFactory.getLogger(EhcacheAggregationRepository.class);
 
     private CamelContext camelContext;
     private CacheManager cacheManager;
+    @Metadata(description = "Name of cache", required = true)
     private String cacheName;
     private Cache<String, DefaultExchangeHolder> cache;
-    private boolean allowSerializedHeaders;
 
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
+    private boolean allowSerializedHeaders;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
     private boolean useRecovery = true;
-    private String deadLetterChannel;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
+    private String deadLetterUri;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
     private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.",
+              defaultValue = "3")
     private int maximumRedeliveries = 3;
 
     public CamelContext getCamelContext() {
@@ -88,16 +105,6 @@ public class EhcacheAggregationRepository extends ServiceSupport implements Reco
         this.allowSerializedHeaders = allowSerializedHeaders;
     }
 
-    @Override
-    public void setDeadLetterUri(String deadLetterUri) {
-        this.deadLetterChannel = deadLetterUri;
-    }
-
-    @Override
-    public String getDeadLetterUri() {
-        return deadLetterChannel;
-    }
-
     @Override
     public boolean isUseRecovery() {
         return useRecovery;
@@ -108,12 +115,12 @@ public class EhcacheAggregationRepository extends ServiceSupport implements Reco
         this.useRecovery = useRecovery;
     }
 
-    public String getDeadLetterChannel() {
-        return deadLetterChannel;
+    public String getDeadLetterUri() {
+        return deadLetterUri;
     }
 
-    public void setDeadLetterChannel(String deadLetterChannel) {
-        this.deadLetterChannel = deadLetterChannel;
+    public void setDeadLetterUri(String deadLetterUri) {
+        this.deadLetterUri = deadLetterUri;
     }
 
     public long getRecoveryInterval() {
@@ -213,6 +220,7 @@ public class EhcacheAggregationRepository extends ServiceSupport implements Reco
 
     @Override
     protected void doStop() throws Exception {
+        // noop
     }
 
     public static Exchange unmarshallExchange(CamelContext camelContext, DefaultExchangeHolder holder) {
diff --git a/components/camel-ehcache/src/main/java/org/apache/camel/component/ehcache/processor/idempotent/EhcacheIdempotentRepository.java b/components/camel-ehcache/src/main/java/org/apache/camel/component/ehcache/processor/idempotent/EhcacheIdempotentRepository.java
index 2606374905a..576e339a444 100644
--- a/components/camel-ehcache/src/main/java/org/apache/camel/component/ehcache/processor/idempotent/EhcacheIdempotentRepository.java
+++ b/components/camel-ehcache/src/main/java/org/apache/camel/component/ehcache/processor/idempotent/EhcacheIdempotentRepository.java
@@ -20,14 +20,21 @@ import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.component.ehcache.EhcacheManager;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.service.ServiceSupport;
 import org.ehcache.Cache;
 import org.ehcache.CacheManager;
 
-@ManagedResource(description = "Ehcache based message id repository")
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses EHCache cache to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
+@ManagedResource(description = "EHCache based message id repository")
 public class EhcacheIdempotentRepository extends ServiceSupport implements IdempotentRepository {
 
+    @Metadata(description = "Name of cache", defaultValue = "EhcacheIdempotentRepository")
     private String cacheName;
     private Cache<String, Boolean> cache;
     private EhcacheManager cacheManager;
@@ -41,6 +48,10 @@ public class EhcacheIdempotentRepository extends ServiceSupport implements Idemp
         this.cacheManager = new EhcacheManager(cacheManager, false, null);
     }
 
+    public void setCacheName(String cacheName) {
+        this.cacheName = cacheName;
+    }
+
     @ManagedAttribute(description = "The processor name")
     public String getCacheName() {
         return cacheName;
diff --git a/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/aggregation/ElastichsearchBulkRequestAggregationStrategyConfigurer.java b/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/aggregation/ElastichsearchBulkRequestAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..36ec2b10107
--- /dev/null
+++ b/components/camel-elasticsearch/src/generated/java/org/apache/camel/component/es/aggregation/ElastichsearchBulkRequestAggregationStrategyConfigurer.java
@@ -0,0 +1,35 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.es.aggregation;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.es.aggregation.ElastichsearchBulkRequestAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class ElastichsearchBulkRequestAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git a/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..dc45b3b8367
--- /dev/null
+++ b/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=ElastichsearchBulkRequestAggregationStrategy
+groupId=org.apache.camel
+artifactId=camel-elasticsearch
+version=4.5.0-SNAPSHOT
+projectName=Camel :: ElasticSearch Java API Client
+projectDescription=Camel ElasticSearch Java API Client support
diff --git a/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/bean/ElastichsearchBulkRequestAggregationStrategy.json b/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/bean/ElastichsearchBulkRequestAggregationStrategy.json
new file mode 100644
index 00000000000..19e93a9e8df
--- /dev/null
+++ b/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/bean/ElastichsearchBulkRequestAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "ElastichsearchBulkRequestAggregationStrategy",
+    "javaType": "org.apache.camel.component.es.aggregation.ElastichsearchBulkRequestAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Elastichsearch Bulk Request Aggregation Strategy",
+    "description": "Aggregates two ElasticSearch BulkOperation into a single BulkRequest",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-elasticsearch",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.es.aggregation.ElastichsearchBulkRequestAggregationStrategy b/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.es.aggregation.ElastichsearchBulkRequestAggregationStrategy
new file mode 100644
index 00000000000..c73733d464a
--- /dev/null
+++ b/components/camel-elasticsearch/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.es.aggregation.ElastichsearchBulkRequestAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.es.aggregation.ElastichsearchBulkRequestAggregationStrategyConfigurer
diff --git a/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/aggregation/BulkRequestAggregationStrategy.java b/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/aggregation/ElastichsearchBulkRequestAggregationStrategy.java
similarity index 83%
rename from components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/aggregation/BulkRequestAggregationStrategy.java
rename to components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/aggregation/ElastichsearchBulkRequestAggregationStrategy.java
index bed13f675ef..9e2a3d8f462 100644
--- a/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/aggregation/BulkRequestAggregationStrategy.java
+++ b/components/camel-elasticsearch/src/main/java/org/apache/camel/component/es/aggregation/ElastichsearchBulkRequestAggregationStrategy.java
@@ -23,11 +23,14 @@ import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
 import org.apache.camel.AggregationStrategy;
 import org.apache.camel.Exchange;
 import org.apache.camel.InvalidPayloadRuntimeException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 
-/**
- * Aggregates two {@link BulkOperation}s into a single {@link BulkRequest}.
- */
-public class BulkRequestAggregationStrategy implements AggregationStrategy {
+@Metadata(label = "bean",
+          description = "Aggregates two ElasticSearch BulkOperation into a single BulkRequest",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
+public class ElastichsearchBulkRequestAggregationStrategy implements AggregationStrategy {
 
     @Override
     public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
diff --git a/components/camel-etcd3/src/generated/java/org/apache/camel/component/etcd3/processor/aggregate/Etcd3AggregationRepositoryConfigurer.java b/components/camel-etcd3/src/generated/java/org/apache/camel/component/etcd3/processor/aggregate/Etcd3AggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..121293342aa
--- /dev/null
+++ b/components/camel-etcd3/src/generated/java/org/apache/camel/component/etcd3/processor/aggregate/Etcd3AggregationRepositoryConfigurer.java
@@ -0,0 +1,91 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.etcd3.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class Etcd3AggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository target = (org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "endpoint":
+        case "Endpoint": target.setEndpoint(property(camelContext, java.lang.String.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "optimistic":
+        case "Optimistic": target.setOptimistic(property(camelContext, boolean.class, value)); return true;
+        case "prefixname":
+        case "PrefixName": target.setPrefixName(property(camelContext, java.lang.String.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "endpoint":
+        case "Endpoint": return java.lang.String.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "optimistic":
+        case "Optimistic": return boolean.class;
+        case "prefixname":
+        case "PrefixName": return java.lang.String.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository target = (org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "endpoint":
+        case "Endpoint": return target.getEndpoint();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "optimistic":
+        case "Optimistic": return target.isOptimistic();
+        case "prefixname":
+        case "PrefixName": return target.getPrefixName();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..546b01b42d2
--- /dev/null
+++ b/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=Etcd3AggregationRepository
+groupId=org.apache.camel
+artifactId=camel-etcd3
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Etcd3
+projectDescription=Camel EtcD v3 component based on jetcd
diff --git a/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/bean/Etcd3AggregationRepository.json b/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/bean/Etcd3AggregationRepository.json
new file mode 100644
index 00000000000..75a6d2e53a6
--- /dev/null
+++ b/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/bean/Etcd3AggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "Etcd3AggregationRepository",
+    "javaType": "org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Etcd3 Aggregation Repository",
+    "description": "Aggregation repository that uses Etcd3 to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-etcd3",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "endpoint": { "index": 0, "kind": "property", "displayName": "Endpoint", "required": true, "type": "object", "javaType": "org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "URL to Etcd3 service" }, "prefixName": { "index": 1, "kind": "property", "displayName": "Prefix Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.etcd3.processor [...]
+  }
+}
+
diff --git a/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository b/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository
new file mode 100644
index 00000000000..e56a8e3dd2b
--- /dev/null
+++ b/components/camel-etcd3/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.etcd3.processor.aggregate.Etcd3AggregationRepositoryConfigurer
diff --git a/components/camel-etcd3/src/main/java/org/apache/camel/component/etcd3/processor/aggregate/Etcd3AggregationRepository.java b/components/camel-etcd3/src/main/java/org/apache/camel/component/etcd3/processor/aggregate/Etcd3AggregationRepository.java
index 83a3e661fd8..03b10fb4d4b 100644
--- a/components/camel-etcd3/src/main/java/org/apache/camel/component/etcd3/processor/aggregate/Etcd3AggregationRepository.java
+++ b/components/camel-etcd3/src/main/java/org/apache/camel/component/etcd3/processor/aggregate/Etcd3AggregationRepository.java
@@ -47,6 +47,8 @@ import io.etcd.jetcd.options.PutOption;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.OptimisticLockingAggregationRepository;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.DefaultExchange;
@@ -56,22 +58,38 @@ import org.apache.camel.util.StringHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses Etcd3 to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class Etcd3AggregationRepository extends ServiceSupport
         implements RecoverableAggregationRepository, OptimisticLockingAggregationRepository {
     private static final Logger LOG = LoggerFactory.getLogger(Etcd3AggregationRepository.class);
     private static final String COMPLETED_SUFFIX = "-completed";
 
-    private boolean optimistic;
-    private boolean useRecovery = true;
+    @Metadata(description = "URL to Etcd3 service", required = true)
     private String endpoint;
     private Client client;
     private boolean shutdownClient;
     private KV kvClient;
+    @Metadata(description = "Prefix to use as primary key", required = true)
     private String prefixName;
+    @Metadata(label = "advanced", description = "Prefix to use as primary key for completed exchanges")
     private String persistencePrefixName;
-    private String deadLetterChannel;
+    @Metadata(description = "Whether or not to use optimistic locking")
+    private boolean optimistic;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
+    private boolean useRecovery = true;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
     private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
+    private String deadLetterUri;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.",
+              defaultValue = "3")
     private int maximumRedeliveries = 3;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
     private boolean allowSerializedHeaders;
 
     public Etcd3AggregationRepository() {
@@ -254,13 +272,13 @@ public class Etcd3AggregationRepository extends ServiceSupport
     }
 
     @Override
-    public void setRecoveryInterval(long interval) {
-        this.recoveryInterval = interval;
+    public long getRecoveryInterval() {
+        return recoveryInterval;
     }
 
     @Override
-    public long getRecoveryIntervalInMillis() {
-        return recoveryInterval;
+    public void setRecoveryInterval(long interval) {
+        this.recoveryInterval = interval;
     }
 
     @Override
@@ -275,12 +293,12 @@ public class Etcd3AggregationRepository extends ServiceSupport
 
     @Override
     public void setDeadLetterUri(String deadLetterUri) {
-        this.deadLetterChannel = deadLetterUri;
+        this.deadLetterUri = deadLetterUri;
     }
 
     @Override
     public String getDeadLetterUri() {
-        return deadLetterChannel;
+        return deadLetterUri;
     }
 
     @Override
@@ -516,7 +534,9 @@ public class Etcd3AggregationRepository extends ServiceSupport
         if (recoveryInterval < 0) {
             throw new IllegalArgumentException("Recovery interval must be zero or a positive integer.");
         }
-
+        if (persistencePrefixName == null && prefixName != null) {
+            this.persistencePrefixName = String.format("%s%s", prefixName, COMPLETED_SUFFIX);
+        }
     }
 
     @Override
diff --git a/components/camel-hazelcast/src/generated/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepositoryConfigurer.java b/components/camel-hazelcast/src/generated/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..e4c7678f4a9
--- /dev/null
+++ b/components/camel-hazelcast/src/generated/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepositoryConfigurer.java
@@ -0,0 +1,79 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate.hazelcast;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class HazelcastAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository target = (org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "hazelcastinstance":
+        case "HazelcastInstance": target.setHazelcastInstance(property(camelContext, com.hazelcast.core.HazelcastInstance.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "hazelcastinstance":
+        case "HazelcastInstance": return com.hazelcast.core.HazelcastInstance.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository target = (org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "hazelcastinstance":
+        case "HazelcastInstance": return target.getHazelcastInstance();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-hazelcast/src/generated/java/org/apache/camel/processor/idempotent/hazelcast/HazelcastIdempotentRepositoryConfigurer.java b/components/camel-hazelcast/src/generated/java/org/apache/camel/processor/idempotent/hazelcast/HazelcastIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..1e8a95cd297
--- /dev/null
+++ b/components/camel-hazelcast/src/generated/java/org/apache/camel/processor/idempotent/hazelcast/HazelcastIdempotentRepositoryConfigurer.java
@@ -0,0 +1,35 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.idempotent.hazelcast;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class HazelcastIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git a/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..15b552fe87b
--- /dev/null
+++ b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=HazelcastAggregationRepository HazelcastIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-hazelcast
+version=4.5.0-SNAPSHOT
+projectName=Camel :: HazelCast
+projectDescription=Camel HazelCast based work queue implementation
diff --git a/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean/HazelcastAggregationRepository.json b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean/HazelcastAggregationRepository.json
new file mode 100644
index 00000000000..d21f0647b3f
--- /dev/null
+++ b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean/HazelcastAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "HazelcastAggregationRepository",
+    "javaType": "org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Hazelcast Aggregation Repository",
+    "description": "Aggregation repository that uses Hazelcast Cache to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-hazelcast",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "mapName": { "index": 0, "kind": "property", "displayName": "Map Name", "required": true, "type": "object", "javaType": "org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache to use" }, "hazelcastInstance": { "index": 1, "kind": "property", "displayName": "Hazelcast Instance", "required": false, "type": "object", "javaType": "org.apache.camel.processor.agg [...]
+  }
+}
+
diff --git a/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean/HazelcastIdempotentRepository.json b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean/HazelcastIdempotentRepository.json
new file mode 100644
index 00000000000..87c881c225e
--- /dev/null
+++ b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/bean/HazelcastIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "HazelcastIdempotentRepository",
+    "javaType": "org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Hazelcast Idempotent Repository",
+    "description": "Idempotent repository that uses Hazelcast cache to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-hazelcast",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "repositoryName": { "index": 0, "kind": "property", "displayName": "Repository Name", "required": false, "type": "object", "javaType": "org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "HazelcastIdempotentRepository", "description": "Name of cache to use" }, "hazelcastInstance": { "index": 1, "kind": "property", "displayName": "Hazelcast Instance", "required": fals [...]
+  }
+}
+
diff --git a/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository
new file mode 100644
index 00000000000..d3a244f68c0
--- /dev/null
+++ b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.hazelcast.HazelcastAggregationRepositoryConfigurer
diff --git a/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepository b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepository
new file mode 100644
index 00000000000..6ab2f65a5a9
--- /dev/null
+++ b/components/camel-hazelcast/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.idempotent.hazelcast.HazelcastIdempotentRepositoryConfigurer
diff --git a/components/camel-hazelcast/src/main/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepository.java b/components/camel-hazelcast/src/main/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepository.java
index db4325b3561..0e474f233dc 100644
--- a/components/camel-hazelcast/src/main/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepository.java
+++ b/components/camel-hazelcast/src/main/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepository.java
@@ -32,6 +32,8 @@ import com.hazelcast.transaction.TransactionalMap;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.OptimisticLockingAggregationRepository;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.DefaultExchange;
@@ -51,8 +53,11 @@ import org.slf4j.LoggerFactory;
  * are gained this way. If the {@link HazelcastAggregationRepository} uses it's own local {@link HazelcastInstance} it
  * will DESTROY this instance on {@link #doStop()}. You should control {@link HazelcastInstance} lifecycle yourself
  * whenever you instantiate {@link HazelcastAggregationRepository} passing a reference to the instance.
- *
  */
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses Hazelcast Cache to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class HazelcastAggregationRepository extends ServiceSupport
         implements RecoverableAggregationRepository,
         OptimisticLockingAggregationRepository {
@@ -61,19 +66,34 @@ public class HazelcastAggregationRepository extends ServiceSupport
 
     private static final Logger LOG = LoggerFactory.getLogger(HazelcastAggregationRepository.class.getName());
 
-    protected boolean optimistic;
     protected boolean useLocalHzInstance;
-    protected boolean useRecovery = true;
     protected IMap<String, DefaultExchangeHolder> cache;
     protected IMap<String, DefaultExchangeHolder> persistedCache;
-    protected HazelcastInstance hzInstance;
+    @Metadata(description = "Name of cache to use", required = true)
     protected String mapName;
+    @Metadata(description = "To use an existing Hazelcast instance instead of local")
+    protected HazelcastInstance hazelcastInstance;
+    @Metadata(label = "advanced", description = "Name of cache to use for completed exchanges")
     protected String persistenceMapName;
-    protected String deadLetterChannel;
+    @Metadata(description = "Whether to use optimistic locking")
+    protected boolean optimistic;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
+    protected boolean useRecovery = true;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
     protected long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
+    protected String deadLetterUri;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.",
+              defaultValue = "3")
     protected int maximumRedeliveries = 3;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
     protected boolean allowSerializedHeaders;
 
+    public HazelcastAggregationRepository() {
+    }
+
     /**
      * Creates new {@link HazelcastAggregationRepository} that defaults to non-optimistic locking with recoverable
      * behavior and a local Hazelcast instance. Recoverable repository name defaults to {@code repositoryName} +
@@ -84,8 +104,6 @@ public class HazelcastAggregationRepository extends ServiceSupport
     public HazelcastAggregationRepository(final String repositoryName) {
         mapName = repositoryName;
         persistenceMapName = String.format("%s%s", mapName, COMPLETED_SUFFIX);
-        optimistic = false;
-        useLocalHzInstance = true;
     }
 
     /**
@@ -98,8 +116,6 @@ public class HazelcastAggregationRepository extends ServiceSupport
     public HazelcastAggregationRepository(final String repositoryName, final String persistentRepositoryName) {
         mapName = repositoryName;
         persistenceMapName = persistentRepositoryName;
-        optimistic = false;
-        useLocalHzInstance = true;
     }
 
     /**
@@ -112,7 +128,6 @@ public class HazelcastAggregationRepository extends ServiceSupport
     public HazelcastAggregationRepository(final String repositoryName, boolean optimistic) {
         this(repositoryName);
         this.optimistic = optimistic;
-        useLocalHzInstance = true;
     }
 
     /**
@@ -126,7 +141,6 @@ public class HazelcastAggregationRepository extends ServiceSupport
                                           boolean optimistic) {
         this(repositoryName, persistentRepositoryName);
         this.optimistic = optimistic;
-        useLocalHzInstance = true;
     }
 
     /**
@@ -138,8 +152,7 @@ public class HazelcastAggregationRepository extends ServiceSupport
      */
     public HazelcastAggregationRepository(final String repositoryName, HazelcastInstance hzInstanse) {
         this(repositoryName, false);
-        this.hzInstance = hzInstanse;
-        useLocalHzInstance = false;
+        this.hazelcastInstance = hzInstanse;
     }
 
     /**
@@ -153,8 +166,7 @@ public class HazelcastAggregationRepository extends ServiceSupport
     public HazelcastAggregationRepository(final String repositoryName, final String persistentRepositoryName,
                                           HazelcastInstance hzInstanse) {
         this(repositoryName, persistentRepositoryName, false);
-        this.hzInstance = hzInstanse;
-        useLocalHzInstance = false;
+        this.hazelcastInstance = hzInstanse;
     }
 
     /**
@@ -167,8 +179,7 @@ public class HazelcastAggregationRepository extends ServiceSupport
      */
     public HazelcastAggregationRepository(final String repositoryName, boolean optimistic, HazelcastInstance hzInstance) {
         this(repositoryName, optimistic);
-        this.hzInstance = hzInstance;
-        useLocalHzInstance = false;
+        this.hazelcastInstance = hzInstance;
     }
 
     /**
@@ -182,8 +193,7 @@ public class HazelcastAggregationRepository extends ServiceSupport
     public HazelcastAggregationRepository(final String repositoryName, final String persistentRepositoryName,
                                           boolean optimistic, HazelcastInstance hzInstance) {
         this(repositoryName, persistentRepositoryName, optimistic);
-        this.hzInstance = hzInstance;
-        useLocalHzInstance = false;
+        this.hazelcastInstance = hzInstance;
     }
 
     @Override
@@ -223,7 +233,7 @@ public class HazelcastAggregationRepository extends ServiceSupport
             throw new UnsupportedOperationException();
         }
         LOG.trace("Adding an Exchange with ID {} for key {} in a thread-safe manner.", exchange.getExchangeId(), key);
-        Lock l = hzInstance.getCPSubsystem().getLock(mapName);
+        Lock l = hazelcastInstance.getCPSubsystem().getLock(mapName);
         try {
             l.lock();
             DefaultExchangeHolder newHolder = DefaultExchangeHolder.marshal(exchange, true, allowSerializedHeaders);
@@ -267,7 +277,7 @@ public class HazelcastAggregationRepository extends ServiceSupport
     }
 
     @Override
-    public long getRecoveryIntervalInMillis() {
+    public long getRecoveryInterval() {
         return recoveryInterval;
     }
 
@@ -283,12 +293,12 @@ public class HazelcastAggregationRepository extends ServiceSupport
 
     @Override
     public void setDeadLetterUri(String deadLetterUri) {
-        this.deadLetterChannel = deadLetterUri;
+        this.deadLetterUri = deadLetterUri;
     }
 
     @Override
     public String getDeadLetterUri() {
-        return deadLetterChannel;
+        return deadLetterUri;
     }
 
     @Override
@@ -327,6 +337,14 @@ public class HazelcastAggregationRepository extends ServiceSupport
         this.allowSerializedHeaders = allowSerializedHeaders;
     }
 
+    public HazelcastInstance getHazelcastInstance() {
+        return hazelcastInstance;
+    }
+
+    public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
+        this.hazelcastInstance = hazelcastInstance;
+    }
+
     /**
      * This method performs transactional operation on removing the {@code exchange} from the operational storage and
      * moving it into the persistent one if the {@link HazelcastAggregationRepository} runs in recoverable mode and
@@ -364,7 +382,7 @@ public class HazelcastAggregationRepository extends ServiceSupport
                 TransactionOptions tOpts = new TransactionOptions();
 
                 tOpts.setTransactionType(TransactionOptions.TransactionType.ONE_PHASE);
-                TransactionContext tCtx = hzInstance.newTransactionContext(tOpts);
+                TransactionContext tCtx = hazelcastInstance.newTransactionContext(tOpts);
 
                 try {
                     tCtx.beginTransaction();
@@ -419,31 +437,35 @@ public class HazelcastAggregationRepository extends ServiceSupport
 
     @Override
     protected void doStart() throws Exception {
+        StringHelper.notEmpty(mapName, "repositoryName");
         if (maximumRedeliveries < 0) {
             throw new IllegalArgumentException("Maximum redelivery retries must be zero or a positive integer.");
         }
         if (recoveryInterval < 0) {
             throw new IllegalArgumentException("Recovery interval must be zero or a positive integer.");
         }
-        StringHelper.notEmpty(mapName, "repositoryName");
-        if (useLocalHzInstance) {
+        if (persistenceMapName == null) {
+            persistenceMapName = String.format("%s%s", mapName, COMPLETED_SUFFIX);
+        }
+        if (hazelcastInstance == null) {
+            useLocalHzInstance = true;
             Config cfg = new XmlConfigBuilder().build();
             cfg.setProperty("hazelcast.version.check.enabled", "false");
-            hzInstance = Hazelcast.newHazelcastInstance(cfg);
+            hazelcastInstance = Hazelcast.newHazelcastInstance(cfg);
         } else {
-            ObjectHelper.notNull(hzInstance, "hzInstanse");
+            ObjectHelper.notNull(hazelcastInstance, "hazelcastInstance");
         }
-        cache = hzInstance.getMap(mapName);
+        cache = hazelcastInstance.getMap(mapName);
         if (useRecovery) {
-            persistedCache = hzInstance.getMap(persistenceMapName);
+            persistedCache = hazelcastInstance.getMap(persistenceMapName);
         }
     }
 
     @Override
     protected void doStop() throws Exception {
-        //noop
         if (useLocalHzInstance) {
-            hzInstance.getLifecycleService().shutdown();
+            hazelcastInstance.getLifecycleService().shutdown();
+            hazelcastInstance = null;
         }
     }
 
diff --git a/components/camel-hazelcast/src/main/java/org/apache/camel/processor/aggregate/hazelcast/ReplicatedHazelcastAggregationRepository.java b/components/camel-hazelcast/src/main/java/org/apache/camel/processor/aggregate/hazelcast/ReplicatedHazelcastAggregationRepository.java
index 84ca8ca45d2..fc83d30c9c9 100644
--- a/components/camel-hazelcast/src/main/java/org/apache/camel/processor/aggregate/hazelcast/ReplicatedHazelcastAggregationRepository.java
+++ b/components/camel-hazelcast/src/main/java/org/apache/camel/processor/aggregate/hazelcast/ReplicatedHazelcastAggregationRepository.java
@@ -50,13 +50,15 @@ import org.slf4j.LoggerFactory;
  * {@link HazelcastInstance} it will DESTROY this instance on {@link #doStop()}. You should control
  * {@link HazelcastInstance} lifecycle yourself whenever you instantiate
  * {@link ReplicatedHazelcastAggregationRepository} passing a reference to the instance.
- *
  */
 public class ReplicatedHazelcastAggregationRepository extends HazelcastAggregationRepository {
     private static final Logger LOG = LoggerFactory.getLogger(ReplicatedHazelcastAggregationRepository.class.getName());
     protected Map<String, DefaultExchangeHolder> replicatedCache;
     protected Map<String, DefaultExchangeHolder> replicatedPersistedCache;
 
+    public ReplicatedHazelcastAggregationRepository() {
+    }
+
     /**
      * Creates new {@link ReplicatedHazelcastAggregationRepository} that defaults to non-optimistic locking with
      * recoverable behavior and a local Hazelcast instance. Recoverable repository name defaults to
@@ -190,7 +192,7 @@ public class ReplicatedHazelcastAggregationRepository extends HazelcastAggregati
             throw new UnsupportedOperationException();
         }
         LOG.trace("Adding an Exchange with ID {} for key {} in a thread-safe manner.", exchange.getExchangeId(), key);
-        Lock l = hzInstance.getCPSubsystem().getLock(mapName);
+        Lock l = hazelcastInstance.getCPSubsystem().getLock(mapName);
         try {
             l.lock();
             DefaultExchangeHolder newHolder = DefaultExchangeHolder.marshal(exchange, true, allowSerializedHeaders);
@@ -279,7 +281,7 @@ public class ReplicatedHazelcastAggregationRepository extends HazelcastAggregati
                 TransactionOptions tOpts = new TransactionOptions();
 
                 tOpts.setTransactionType(TransactionOptions.TransactionType.ONE_PHASE);
-                TransactionContext tCtx = hzInstance.newTransactionContext(tOpts);
+                TransactionContext tCtx = hazelcastInstance.newTransactionContext(tOpts);
 
                 try {
                     tCtx.beginTransaction();
@@ -334,16 +336,17 @@ public class ReplicatedHazelcastAggregationRepository extends HazelcastAggregati
             throw new IllegalArgumentException("Recovery interval must be zero or a positive integer.");
         }
         StringHelper.notEmpty(mapName, "repositoryName");
-        if (useLocalHzInstance) {
+        if (hazelcastInstance == null) {
+            useLocalHzInstance = true;
             Config cfg = new XmlConfigBuilder().build();
             cfg.setProperty("hazelcast.version.check.enabled", "false");
-            hzInstance = Hazelcast.newHazelcastInstance(cfg);
+            hazelcastInstance = Hazelcast.newHazelcastInstance(cfg);
         } else {
-            ObjectHelper.notNull(hzInstance, "hzInstanse");
+            ObjectHelper.notNull(hazelcastInstance, "hazelcastInstance");
         }
-        replicatedCache = hzInstance.getReplicatedMap(mapName);
+        replicatedCache = hazelcastInstance.getReplicatedMap(mapName);
         if (useRecovery) {
-            replicatedPersistedCache = hzInstance.getReplicatedMap(persistenceMapName);
+            replicatedPersistedCache = hazelcastInstance.getReplicatedMap(persistenceMapName);
         }
     }
 
diff --git a/components/camel-hazelcast/src/main/java/org/apache/camel/processor/idempotent/hazelcast/HazelcastIdempotentRepository.java b/components/camel-hazelcast/src/main/java/org/apache/camel/processor/idempotent/hazelcast/HazelcastIdempotentRepository.java
index 52827004684..2a08d74219f 100644
--- a/components/camel-hazelcast/src/main/java/org/apache/camel/processor/idempotent/hazelcast/HazelcastIdempotentRepository.java
+++ b/components/camel-hazelcast/src/main/java/org/apache/camel/processor/idempotent/hazelcast/HazelcastIdempotentRepository.java
@@ -16,34 +16,62 @@
  */
 package org.apache.camel.processor.idempotent.hazelcast;
 
+import com.hazelcast.config.Config;
+import com.hazelcast.config.XmlConfigBuilder;
+import com.hazelcast.core.Hazelcast;
 import com.hazelcast.core.HazelcastInstance;
 import com.hazelcast.map.IMap;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.ObjectHelper;
 
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses Hazelcast cache to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 public class HazelcastIdempotentRepository extends ServiceSupport implements IdempotentRepository {
 
+    protected boolean useLocalHzInstance;
+
+    @Metadata(description = "Name of cache to use", defaultValue = "HazelcastIdempotentRepository")
     private String repositoryName;
     private IMap<String, Boolean> repo;
+    @Metadata(description = "To use an existing Hazelcast instance instead of local")
     private HazelcastInstance hazelcastInstance;
 
+    public HazelcastIdempotentRepository() {
+        this(null);
+    }
+
     public HazelcastIdempotentRepository(HazelcastInstance hazelcastInstance) {
         this(hazelcastInstance, HazelcastIdempotentRepository.class.getSimpleName());
     }
 
     public HazelcastIdempotentRepository(HazelcastInstance hazelcastInstance, String repositoryName) {
-        this.repositoryName = repositoryName;
         this.hazelcastInstance = hazelcastInstance;
+        this.repositoryName = repositoryName;
     }
 
     @Override
     protected void doStart() throws Exception {
+        if (hazelcastInstance == null) {
+            Config cfg = new XmlConfigBuilder().build();
+            cfg.setProperty("hazelcast.version.check.enabled", "false");
+            hazelcastInstance = Hazelcast.newHazelcastInstance(cfg);
+            useLocalHzInstance = true;
+        } else {
+            ObjectHelper.notNull(hazelcastInstance, "hazelcastInstance");
+        }
         repo = hazelcastInstance.getMap(repositoryName);
     }
 
     @Override
     protected void doStop() throws Exception {
-        // noop
+        if (useLocalHzInstance) {
+            hazelcastInstance.getLifecycleService().shutdown();
+        }
     }
 
     @Override
diff --git a/components/camel-hazelcast/src/test/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepositoryConstructorsTest.java b/components/camel-hazelcast/src/test/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepositoryConstructorsTest.java
index 67e86821feb..86f1404ec94 100644
--- a/components/camel-hazelcast/src/test/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepositoryConstructorsTest.java
+++ b/components/camel-hazelcast/src/test/java/org/apache/camel/processor/aggregate/hazelcast/HazelcastAggregationRepositoryConstructorsTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.processor.aggregate.hazelcast;
 
-import com.hazelcast.core.HazelcastInstance;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.support.DefaultExchange;
@@ -64,14 +63,6 @@ public class HazelcastAggregationRepositoryConstructorsTest extends CamelTestSup
         }
     }
 
-    @Test
-    public void uninitializedHazelcastInstanceThrows() throws Exception {
-        final String repoName = "hzRepoMap";
-        HazelcastAggregationRepository repo = new HazelcastAggregationRepository(repoName, (HazelcastInstance) null);
-        assertThrows(IllegalArgumentException.class,
-                () -> repo.doStart());
-    }
-
     @Test
     public void locallyInitializedHazelcastInstanceAdd() {
         assertDoesNotThrow(() -> runLocallyInitializedHazelcastInstanceAdd());
diff --git a/components/camel-infinispan/camel-infinispan-common/src/main/java/org/apache/camel/component/infinispan/InfinispanAggregationRepository.java b/components/camel-infinispan/camel-infinispan-common/src/main/java/org/apache/camel/component/infinispan/InfinispanAggregationRepository.java
index 3543a5dd63c..5d6e783ec58 100644
--- a/components/camel-infinispan/camel-infinispan-common/src/main/java/org/apache/camel/component/infinispan/InfinispanAggregationRepository.java
+++ b/components/camel-infinispan/camel-infinispan-common/src/main/java/org/apache/camel/component/infinispan/InfinispanAggregationRepository.java
@@ -23,10 +23,12 @@ import java.util.concurrent.TimeUnit;
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.DefaultExchange;
 import org.apache.camel.support.DefaultExchangeHolder;
 import org.apache.camel.support.service.ServiceSupport;
+import org.apache.camel.util.ObjectHelper;
 import org.infinispan.commons.api.BasicCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,15 +39,27 @@ public abstract class InfinispanAggregationRepository
 
     private static final Logger LOG = LoggerFactory.getLogger(InfinispanAggregationRepository.class);
 
-    private final String cacheName;
-
     private CamelContext camelContext;
+
+    @Metadata(description = "Name of cache", required = true)
+    private String cacheName;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
     private boolean useRecovery = true;
-    private String deadLetterChannel;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
+    private String deadLetterUri;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
     private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.",
+              defaultValue = "3")
     private int maximumRedeliveries = 3;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
     private boolean allowSerializedHeaders;
 
+    public InfinispanAggregationRepository() {
+    }
+
     /**
      * Creates new {@link InfinispanAggregationRepository} that defaults to non-optimistic locking with recoverable
      * behavior and a local Infinispan cache.
@@ -110,19 +124,23 @@ public abstract class InfinispanAggregationRepository
         return useRecovery ? unmarshallExchange(camelContext, getCache().get(exchangeId)) : null;
     }
 
+    public void setCacheName(String cacheName) {
+        this.cacheName = cacheName;
+    }
+
     @Override
     public void setRecoveryInterval(long interval, TimeUnit timeUnit) {
         this.recoveryInterval = timeUnit.toMillis(interval);
     }
 
     @Override
-    public void setRecoveryInterval(long interval) {
-        this.recoveryInterval = interval;
+    public long getRecoveryInterval() {
+        return recoveryInterval;
     }
 
     @Override
-    public long getRecoveryIntervalInMillis() {
-        return recoveryInterval;
+    public void setRecoveryInterval(long interval) {
+        this.recoveryInterval = interval;
     }
 
     @Override
@@ -135,16 +153,6 @@ public abstract class InfinispanAggregationRepository
         this.useRecovery = useRecovery;
     }
 
-    @Override
-    public String getDeadLetterUri() {
-        return deadLetterChannel;
-    }
-
-    @Override
-    public void setDeadLetterUri(String deadLetterUri) {
-        this.deadLetterChannel = deadLetterUri;
-    }
-
     @Override
     public int getMaximumRedeliveries() {
         return maximumRedeliveries;
@@ -157,6 +165,7 @@ public abstract class InfinispanAggregationRepository
 
     @Override
     protected void doStart() throws Exception {
+        ObjectHelper.notNull(cacheName, "cacheName", this);
         if (maximumRedeliveries < 0) {
             throw new IllegalArgumentException("Maximum redelivery retries must be zero or a positive integer.");
         }
@@ -178,12 +187,12 @@ public abstract class InfinispanAggregationRepository
         return cacheName;
     }
 
-    public String getDeadLetterChannel() {
-        return deadLetterChannel;
+    public String getDeadLetterUri() {
+        return deadLetterUri;
     }
 
-    public void setDeadLetterChannel(String deadLetterChannel) {
-        this.deadLetterChannel = deadLetterChannel;
+    public void setDeadLetterUri(String deadLetterUri) {
+        this.deadLetterUri = deadLetterUri;
     }
 
     public boolean isAllowSerializedHeaders() {
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/generated/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedAggregationRepositoryConfigurer.java b/components/camel-infinispan/camel-infinispan-embedded/src/generated/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..a16e2a9b2b7
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/generated/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedAggregationRepositoryConfigurer.java
@@ -0,0 +1,85 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.infinispan.embedded;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class InfinispanEmbeddedAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository target = (org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "cachename":
+        case "CacheName": target.setCacheName(property(camelContext, java.lang.String.class, value)); return true;
+        case "configuration":
+        case "Configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedConfiguration.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "cachename":
+        case "CacheName": return java.lang.String.class;
+        case "configuration":
+        case "Configuration": return org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedConfiguration.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository target = (org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "cachename":
+        case "CacheName": return target.getCacheName();
+        case "configuration":
+        case "Configuration": return target.getConfiguration();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/generated/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedIdempotentRepositoryConfigurer.java b/components/camel-infinispan/camel-infinispan-embedded/src/generated/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..81e8f25166e
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/generated/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedIdempotentRepositoryConfigurer.java
@@ -0,0 +1,61 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.infinispan.embedded;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class InfinispanEmbeddedIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository target = (org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachecontainer":
+        case "CacheContainer": target.setCacheContainer(property(camelContext, org.infinispan.manager.EmbeddedCacheManager.class, value)); return true;
+        case "cachename":
+        case "CacheName": target.setCacheName(property(camelContext, java.lang.String.class, value)); return true;
+        case "configuration":
+        case "Configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedConfiguration.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachecontainer":
+        case "CacheContainer": return org.infinispan.manager.EmbeddedCacheManager.class;
+        case "cachename":
+        case "CacheName": return java.lang.String.class;
+        case "configuration":
+        case "Configuration": return org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedConfiguration.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository target = (org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachecontainer":
+        case "CacheContainer": return target.getCacheContainer();
+        case "cachename":
+        case "CacheName": return target.getCacheName();
+        case "configuration":
+        case "Configuration": return target.getConfiguration();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..6f8a8171884
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=InfinispanEmbeddedAggregationRepository InfinispanEmbeddedIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-infinispan-embedded
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Infinispan :: Embedded
+projectDescription=Camel Infinispan Embedded support
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanEmbeddedAggregationRepository.json b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanEmbeddedAggregationRepository.json
new file mode 100644
index 00000000000..d15dd4d8018
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanEmbeddedAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "InfinispanEmbeddedAggregationRepository",
+    "javaType": "org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Infinispan Embedded Aggregation Repository",
+    "description": "Aggregation repository that uses embedded Infinispan to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-infinispan-embedded",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "configuration": { "index": 1, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.infini [...]
+  }
+}
+
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanEmbeddedIdempotentRepository.json b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanEmbeddedIdempotentRepository.json
new file mode 100644
index 00000000000..2704dc07f79
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanEmbeddedIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "InfinispanEmbeddedIdempotentRepository",
+    "javaType": "org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Infinispan Embedded Idempotent Repository",
+    "description": "Idempotent repository that uses embedded Infinispan to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-infinispan-embedded",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "configuration": { "index": 1, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.infinis [...]
+  }
+}
+
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository
new file mode 100644
index 00000000000..ea7bc300247
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedAggregationRepositoryConfigurer
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository
new file mode 100644
index 00000000000..6f247c58e11
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.infinispan.embedded.InfinispanEmbeddedIdempotentRepositoryConfigurer
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/main/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedAggregationRepository.java b/components/camel-infinispan/camel-infinispan-embedded/src/main/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedAggregationRepository.java
index 36b084040c9..3d329f297e7 100644
--- a/components/camel-infinispan/camel-infinispan-embedded/src/main/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedAggregationRepository.java
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/main/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedAggregationRepository.java
@@ -19,18 +19,45 @@ package org.apache.camel.component.infinispan.embedded;
 import java.util.function.Supplier;
 
 import org.apache.camel.component.infinispan.InfinispanAggregationRepository;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.DefaultExchangeHolder;
 import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.function.Suppliers;
 import org.infinispan.commons.api.BasicCache;
 
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses embedded Infinispan to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class InfinispanEmbeddedAggregationRepository extends InfinispanAggregationRepository {
-    private final Supplier<BasicCache<String, DefaultExchangeHolder>> cache;
 
-    private InfinispanEmbeddedConfiguration configuration;
+    private Supplier<BasicCache<String, DefaultExchangeHolder>> cache;
     private InfinispanEmbeddedManager manager;
 
+    // needed for metadata generation
+    @Metadata(description = "Name of cache", required = true)
+    private String cacheName;
+    @Metadata(description = "Configuration for embedded Infinispan")
+    private InfinispanEmbeddedConfiguration configuration;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
+    private boolean useRecovery = true;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
+    private String deadLetterUri;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
+    private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.",
+              defaultValue = "3")
+    private int maximumRedeliveries = 3;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
+    private boolean allowSerializedHeaders;
+
+    public InfinispanEmbeddedAggregationRepository() {
+    }
+
     /**
      * Creates new {@link InfinispanEmbeddedAggregationRepository} that defaults to non-optimistic locking with
      * recoverable behavior and a local Infinispan cache.
@@ -39,8 +66,6 @@ public class InfinispanEmbeddedAggregationRepository extends InfinispanAggregati
      */
     public InfinispanEmbeddedAggregationRepository(String cacheName) {
         super(cacheName);
-
-        this.cache = Suppliers.memorize(() -> manager.getCache(getCacheName()));
     }
 
     @Override
@@ -53,8 +78,8 @@ public class InfinispanEmbeddedAggregationRepository extends InfinispanAggregati
         if (ObjectHelper.isEmpty(manager)) {
             manager = new InfinispanEmbeddedManager(configuration);
         }
-
         manager.setCamelContext(getCamelContext());
+        this.cache = Suppliers.memorize(() -> manager.getCache(getCacheName()));
 
         ServiceHelper.startService(manager);
     }
@@ -62,7 +87,6 @@ public class InfinispanEmbeddedAggregationRepository extends InfinispanAggregati
     @Override
     protected void doStop() throws Exception {
         super.doStop();
-
         ServiceHelper.stopService(manager);
     }
 
diff --git a/components/camel-infinispan/camel-infinispan-embedded/src/main/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedIdempotentRepository.java b/components/camel-infinispan/camel-infinispan-embedded/src/main/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedIdempotentRepository.java
index b4abfc3e597..28daab8a23e 100644
--- a/components/camel-infinispan/camel-infinispan-embedded/src/main/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedIdempotentRepository.java
+++ b/components/camel-infinispan/camel-infinispan-embedded/src/main/java/org/apache/camel/component/infinispan/embedded/InfinispanEmbeddedIdempotentRepository.java
@@ -20,26 +20,40 @@ import java.util.function.Supplier;
 
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.component.infinispan.InfinispanIdempotentRepository;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.support.service.ServiceHelper;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.function.Suppliers;
 import org.infinispan.commons.api.BasicCache;
 import org.infinispan.manager.EmbeddedCacheManager;
 
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses embedded Infinispan to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 @ManagedResource(description = "Infinispan Embedded message id repository")
 public class InfinispanEmbeddedIdempotentRepository extends InfinispanIdempotentRepository {
-    private final String cacheName;
-    private final Supplier<BasicCache<String, Boolean>> cache;
 
-    private InfinispanEmbeddedConfiguration configuration;
+    private Supplier<BasicCache<String, Boolean>> cache;
     private InfinispanEmbeddedManager manager;
 
+    @Metadata(description = "Name of cache", required = true)
+    private String cacheName;
+    @Metadata(description = "Configuration for embedded Infinispan")
+    private InfinispanEmbeddedConfiguration configuration;
+
+    public InfinispanEmbeddedIdempotentRepository() {
+    }
+
     public InfinispanEmbeddedIdempotentRepository(String cacheName) {
         this.cacheName = cacheName;
-        this.cache = Suppliers.memorize(() -> manager.getCache(getCacheName()));
     }
 
     @Override
     protected void doStart() throws Exception {
         super.doStart();
+        ObjectHelper.notNull(cacheName, "cacheName", this);
 
         if (this.configuration == null) {
             this.configuration = new InfinispanEmbeddedConfiguration();
@@ -47,12 +61,13 @@ public class InfinispanEmbeddedIdempotentRepository extends InfinispanIdempotent
 
         this.manager = new InfinispanEmbeddedManager(configuration);
         this.manager.setCamelContext(getCamelContext());
-        this.manager.start();
+        this.cache = Suppliers.memorize(() -> manager.getCache(getCacheName()));
+        ServiceHelper.startService(manager);
     }
 
     @Override
     protected void doShutdown() throws Exception {
-        this.manager.shutdown();
+        ServiceHelper.stopAndShutdownService(manager);
         super.doShutdown();
     }
 
@@ -61,6 +76,10 @@ public class InfinispanEmbeddedIdempotentRepository extends InfinispanIdempotent
         return cache.get();
     }
 
+    public void setCacheName(String cacheName) {
+        this.cacheName = cacheName;
+    }
+
     @Override
     public String getCacheName() {
         return this.cacheName;
diff --git a/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteAggregationRepositoryConfigurer.java b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..4f84c29643a
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteAggregationRepositoryConfigurer.java
@@ -0,0 +1,85 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.infinispan.remote;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class InfinispanRemoteAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository target = (org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "cachename":
+        case "CacheName": target.setCacheName(property(camelContext, java.lang.String.class, value)); return true;
+        case "configuration":
+        case "Configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "cachename":
+        case "CacheName": return java.lang.String.class;
+        case "configuration":
+        case "Configuration": return org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository target = (org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "cachename":
+        case "CacheName": return target.getCacheName();
+        case "configuration":
+        case "Configuration": return target.getConfiguration();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteIdempotentRepositoryConfigurer.java b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..83ad461789c
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan/src/generated/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteIdempotentRepositoryConfigurer.java
@@ -0,0 +1,55 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.infinispan.remote;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class InfinispanRemoteIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository target = (org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachecontainer":
+        case "CacheContainer": target.setCacheContainer(property(camelContext, org.infinispan.client.hotrod.RemoteCacheManager.class, value)); return true;
+        case "configuration":
+        case "Configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachecontainer":
+        case "CacheContainer": return org.infinispan.client.hotrod.RemoteCacheManager.class;
+        case "configuration":
+        case "Configuration": return org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository target = (org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachecontainer":
+        case "CacheContainer": return target.getCacheContainer();
+        case "configuration":
+        case "Configuration": return target.getConfiguration();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..5312b3771e0
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=InfinispanRemoteAggregationRepository InfinispanRemoteIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-infinispan
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Infinispan :: Remote
+projectDescription=Camel Infinispan Remote support
diff --git a/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanRemoteAggregationRepository.json b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanRemoteAggregationRepository.json
new file mode 100644
index 00000000000..3a9fbe50d11
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanRemoteAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "InfinispanRemoteAggregationRepository",
+    "javaType": "org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Infinispan Remote Aggregation Repository",
+    "description": "Aggregation repository that uses remote Infinispan to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-infinispan",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "configuration": { "index": 1, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.infinispan [...]
+  }
+}
+
diff --git a/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanRemoteIdempotentRepository.json b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanRemoteIdempotentRepository.json
new file mode 100644
index 00000000000..b4d7349e455
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/bean/InfinispanRemoteIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "InfinispanRemoteIdempotentRepository",
+    "javaType": "org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Infinispan Remote Idempotent Repository",
+    "description": "Idempotent repository that uses remote Infinispan to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-infinispan",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheName": { "index": 0, "kind": "property", "displayName": "Cache Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of cache" }, "configuration": { "index": 1, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.infinispan. [...]
+  }
+}
+
diff --git a/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository
new file mode 100644
index 00000000000..dfaf44316bb
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.infinispan.remote.InfinispanRemoteAggregationRepositoryConfigurer
diff --git a/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository
new file mode 100644
index 00000000000..65f11c2cd16
--- /dev/null
+++ b/components/camel-infinispan/camel-infinispan/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.infinispan.remote.InfinispanRemoteIdempotentRepositoryConfigurer
diff --git a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteAggregationRepository.java b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteAggregationRepository.java
index 73cdb91ea63..40279e50707 100644
--- a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteAggregationRepository.java
+++ b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteAggregationRepository.java
@@ -20,6 +20,8 @@ import java.util.function.Supplier;
 
 import org.apache.camel.component.infinispan.InfinispanAggregationRepository;
 import org.apache.camel.component.infinispan.remote.protostream.DefaultExchangeHolderContextInitializer;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.DefaultExchangeHolder;
 import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.util.function.Suppliers;
@@ -28,12 +30,37 @@ import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
 import org.infinispan.commons.api.BasicCache;
 import org.infinispan.commons.configuration.Combine;
 
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses remote Infinispan to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class InfinispanRemoteAggregationRepository extends InfinispanAggregationRepository {
-    private final Supplier<BasicCache<String, DefaultExchangeHolder>> cache;
 
-    private InfinispanRemoteConfiguration configuration;
+    private Supplier<BasicCache<String, DefaultExchangeHolder>> cache;
     private InfinispanRemoteManager manager;
 
+    @Metadata(description = "Name of cache", required = true)
+    private String cacheName;
+    @Metadata(description = "Configuration for remote Infinispan")
+    private InfinispanRemoteConfiguration configuration;
+    // needed for metadata generation
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
+    private boolean useRecovery = true;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
+    private String deadLetterUri;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
+    private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.",
+              defaultValue = "3")
+    private int maximumRedeliveries = 3;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
+    private boolean allowSerializedHeaders;
+
+    public InfinispanRemoteAggregationRepository() {
+    }
+
     /**
      * Creates new {@link InfinispanRemoteAggregationRepository} that defaults to non-optimistic locking with
      * recoverable behavior and a local Infinispan cache.
@@ -42,11 +69,6 @@ public class InfinispanRemoteAggregationRepository extends InfinispanAggregation
      */
     public InfinispanRemoteAggregationRepository(String cacheName) {
         super(cacheName);
-
-        this.cache = Suppliers.memorize(
-                // for optimization reason, a remote cache does not return the previous value for operation
-                // such as Map::put and need to be explicitly forced
-                () -> InfinispanRemoteUtil.getCacheWithFlags(manager, getCacheName(), Flag.FORCE_RETURN_VALUE));
     }
 
     @Override
@@ -71,13 +93,17 @@ public class InfinispanRemoteAggregationRepository extends InfinispanAggregation
         manager = new InfinispanRemoteManager(conf);
         manager.setCamelContext(getCamelContext());
 
+        this.cache = Suppliers.memorize(
+                // for optimization reason, a remote cache does not return the previous value for operation
+                // such as Map::put and need to be explicitly forced
+                () -> InfinispanRemoteUtil.getCacheWithFlags(manager, getCacheName(), Flag.FORCE_RETURN_VALUE));
+
         ServiceHelper.startService(manager);
     }
 
     @Override
     protected void doStop() throws Exception {
         super.doStop();
-
         ServiceHelper.stopService(manager);
     }
 
diff --git a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteIdempotentRepository.java b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteIdempotentRepository.java
index 7832f531550..fef382e6e4f 100644
--- a/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteIdempotentRepository.java
+++ b/components/camel-infinispan/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/remote/InfinispanRemoteIdempotentRepository.java
@@ -20,6 +20,10 @@ import java.util.function.Supplier;
 
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.component.infinispan.InfinispanIdempotentRepository;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.support.service.ServiceHelper;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.function.Suppliers;
 import org.infinispan.client.hotrod.Flag;
 import org.infinispan.client.hotrod.RemoteCache;
@@ -28,22 +32,32 @@ import org.infinispan.commons.api.BasicCache;
 
 import static org.apache.camel.component.infinispan.remote.InfinispanRemoteUtil.getCacheWithFlags;
 
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses remote Infinispan to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 @ManagedResource(description = "Infinispan Remote message id repository")
 public class InfinispanRemoteIdempotentRepository extends InfinispanIdempotentRepository {
-    private final String cacheName;
-    private final Supplier<RemoteCache<String, Boolean>> cache;
 
-    private InfinispanRemoteConfiguration configuration;
+    private Supplier<RemoteCache<String, Boolean>> cache;
     private InfinispanRemoteManager manager;
 
+    @Metadata(description = "Name of cache", required = true)
+    private String cacheName;
+    @Metadata(description = "Configuration for remote Infinispan")
+    private InfinispanRemoteConfiguration configuration;
+
+    public InfinispanRemoteIdempotentRepository() {
+    }
+
     public InfinispanRemoteIdempotentRepository(String cacheName) {
         this.cacheName = cacheName;
-        this.cache = Suppliers.memorize(() -> getCacheWithFlags(manager, cacheName, Flag.FORCE_RETURN_VALUE));
     }
 
     @Override
     protected void doStart() throws Exception {
         super.doStart();
+        ObjectHelper.notNull(cacheName, "cacheName", this);
 
         if (this.configuration == null) {
             this.configuration = new InfinispanRemoteConfiguration();
@@ -51,12 +65,13 @@ public class InfinispanRemoteIdempotentRepository extends InfinispanIdempotentRe
 
         this.manager = new InfinispanRemoteManager(configuration);
         this.manager.setCamelContext(getCamelContext());
-        this.manager.start();
+        this.cache = Suppliers.memorize(() -> getCacheWithFlags(manager, cacheName, Flag.FORCE_RETURN_VALUE));
+        ServiceHelper.startService(manager);
     }
 
     @Override
     protected void doShutdown() throws Exception {
-        this.manager.shutdown();
+        ServiceHelper.stopAndShutdownService(manager);
         super.doShutdown();
     }
 
@@ -94,7 +109,6 @@ public class InfinispanRemoteIdempotentRepository extends InfinispanIdempotentRe
         if (this.configuration == null) {
             this.configuration = new InfinispanRemoteConfiguration();
         }
-
         this.configuration.setCacheContainer(cacheContainer);
     }
 }
diff --git a/components/camel-jcache/src/generated/java/org/apache/camel/component/jcache/processor/aggregate/JCacheAggregationRepositoryConfigurer.java b/components/camel-jcache/src/generated/java/org/apache/camel/component/jcache/processor/aggregate/JCacheAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..8cf4acbe241
--- /dev/null
+++ b/components/camel-jcache/src/generated/java/org/apache/camel/component/jcache/processor/aggregate/JCacheAggregationRepositoryConfigurer.java
@@ -0,0 +1,67 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.jcache.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class JCacheAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository target = (org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "cachename":
+        case "CacheName": target.setCacheName(property(camelContext, java.lang.String.class, value)); return true;
+        case "configuration":
+        case "Configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.jcache.JCacheConfiguration.class, value)); return true;
+        case "optimistic":
+        case "Optimistic": target.setOptimistic(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "cachename":
+        case "CacheName": return java.lang.String.class;
+        case "configuration":
+        case "Configuration": return org.apache.camel.component.jcache.JCacheConfiguration.class;
+        case "optimistic":
+        case "Optimistic": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository target = (org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "cachename":
+        case "CacheName": return target.getCacheName();
+        case "configuration":
+        case "Configuration": return target.getConfiguration();
+        case "optimistic":
+        case "Optimistic": return target.isOptimistic();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-jcache/src/generated/java/org/apache/camel/component/jcache/processor/idempotent/JCacheIdempotentRepositoryConfigurer.java b/components/camel-jcache/src/generated/java/org/apache/camel/component/jcache/processor/idempotent/JCacheIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..3a5ea2b0d22
--- /dev/null
+++ b/components/camel-jcache/src/generated/java/org/apache/camel/component/jcache/processor/idempotent/JCacheIdempotentRepositoryConfigurer.java
@@ -0,0 +1,55 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.jcache.processor.idempotent;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class JCacheIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository target = (org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": target.setCacheName(property(camelContext, java.lang.String.class, value)); return true;
+        case "configuration":
+        case "Configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.jcache.JCacheConfiguration.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": return java.lang.String.class;
+        case "configuration":
+        case "Configuration": return org.apache.camel.component.jcache.JCacheConfiguration.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository target = (org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachename":
+        case "CacheName": return target.getCacheName();
+        case "configuration":
+        case "Configuration": return target.getConfiguration();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-jcache/src/generated/resources/META-INF/org/apache/camel/component/jcache/jcache.json b/components/camel-jcache/src/generated/resources/META-INF/org/apache/camel/component/jcache/jcache.json
index 6a82e6806d9..5e8f5ff9eb2 100644
--- a/components/camel-jcache/src/generated/resources/META-INF/org/apache/camel/component/jcache/jcache.json
+++ b/components/camel-jcache/src/generated/resources/META-INF/org/apache/camel/component/jcache/jcache.json
@@ -44,24 +44,24 @@
   },
   "properties": {
     "cacheName": { "index": 0, "kind": "path", "displayName": "Cache Name", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the cache" },
-    "cacheConfiguration": { "index": 1, "kind": "parameter", "displayName": "Cache Configuration", "group": "common", "label": "", "required": false, "type": "object", "javaType": "javax.cache.configuration.Configuration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "A Configuration for the Cache" },
-    "cacheConfigurationProperties": { "index": 2, "kind": "parameter", "displayName": "Cache Configuration Properties", "group": "common", "label": "", "required": false, "type": "object", "javaType": "java.util.Properties", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The Properties for the javax.cache.spi.CachingProvider to create the CacheM [...]
-    "cachingProvider": { "index": 3, "kind": "parameter", "displayName": "Caching Provider", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The fully qualified class name of the javax.cache.spi.CachingProvider" },
-    "configurationUri": { "index": 4, "kind": "parameter", "displayName": "Configuration Uri", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "An implementation specific URI for the CacheManager" },
-    "managementEnabled": { "index": 5, "kind": "parameter", "displayName": "Management Enabled", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Whether management gathering is enabled" },
-    "readThrough": { "index": 6, "kind": "parameter", "displayName": "Read Through", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If read-through caching should be used" },
-    "statisticsEnabled": { "index": 7, "kind": "parameter", "displayName": "Statistics Enabled", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Whether statistics gathering is enabled" },
-    "storeByValue": { "index": 8, "kind": "parameter", "displayName": "Store By Value", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If cache should use store-by-value or store-by-reference semantics" },
-    "writeThrough": { "index": 9, "kind": "parameter", "displayName": "Write Through", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If write-through caching should be used" },
-    "filteredEvents": { "index": 10, "kind": "parameter", "displayName": "Filtered Events", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "CREATED", "UPDATED", "REMOVED", "EXPIRED" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Events a consumer should filter (multiple [...]
-    "oldValueRequired": { "index": 11, "kind": "parameter", "displayName": "Old Value Required", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "if the old value is required for events" },
-    "synchronous": { "index": 12, "kind": "parameter", "displayName": "Synchronous", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "if the event listener should block the thread causing the event" },
-    "bridgeErrorHandler": { "index": 13, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming [...]
-    "eventFilters": { "index": 14, "kind": "parameter", "displayName": "Event Filters", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<javax.cache.event.CacheEntryEventFilter>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The CacheEntryEventFilter. If using eventFi [...]
-    "exceptionHandler": { "index": 15, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By de [...]
-    "exchangePattern": { "index": 16, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
-    "action": { "index": 17, "kind": "parameter", "displayName": "Action", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "To configure using a cache operation by default. If an operation in the message header, then the operation from th [...]
-    "lazyStartProducer": { "index": 18, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...]
+    "cacheConfigurationProperties": { "index": 1, "kind": "parameter", "displayName": "Cache Configuration Properties", "group": "common", "label": "", "required": false, "type": "object", "javaType": "java.util.Properties", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The Properties for the javax.cache.spi.CachingProvider to create the CacheM [...]
+    "cachingProvider": { "index": 2, "kind": "parameter", "displayName": "Caching Provider", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The fully qualified class name of the javax.cache.spi.CachingProvider" },
+    "configurationUri": { "index": 3, "kind": "parameter", "displayName": "Configuration Uri", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "An implementation specific URI for the CacheManager" },
+    "managementEnabled": { "index": 4, "kind": "parameter", "displayName": "Management Enabled", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Whether management gathering is enabled" },
+    "readThrough": { "index": 5, "kind": "parameter", "displayName": "Read Through", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If read-through caching should be used" },
+    "statisticsEnabled": { "index": 6, "kind": "parameter", "displayName": "Statistics Enabled", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Whether statistics gathering is enabled" },
+    "storeByValue": { "index": 7, "kind": "parameter", "displayName": "Store By Value", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If cache should use store-by-value or store-by-reference semantics" },
+    "writeThrough": { "index": 8, "kind": "parameter", "displayName": "Write Through", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "If write-through caching should be used" },
+    "filteredEvents": { "index": 9, "kind": "parameter", "displayName": "Filtered Events", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "CREATED", "UPDATED", "REMOVED", "EXPIRED" ], "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Events a consumer should filter (multiple  [...]
+    "oldValueRequired": { "index": 10, "kind": "parameter", "displayName": "Old Value Required", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "if the old value is required for events" },
+    "synchronous": { "index": 11, "kind": "parameter", "displayName": "Synchronous", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "if the event listener should block the thread causing the event" },
+    "bridgeErrorHandler": { "index": 12, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions (if possible) occurred while the Camel consumer is trying to pickup incoming [...]
+    "eventFilters": { "index": 13, "kind": "parameter", "displayName": "Event Filters", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "array", "javaType": "java.util.List<javax.cache.event.CacheEntryEventFilter>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The CacheEntryEventFilter. If using eventFi [...]
+    "exceptionHandler": { "index": 14, "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By de [...]
+    "exchangePattern": { "index": 15, "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+    "action": { "index": 16, "kind": "parameter", "displayName": "Action", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "To configure using a cache operation by default. If an operation in the message header, then the operation from th [...]
+    "lazyStartProducer": { "index": 17, "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a produ [...]
+    "cacheConfiguration": { "index": 18, "kind": "parameter", "displayName": "Cache Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.cache.configuration.Configuration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "A Configuration for the Cache" },
     "cacheLoaderFactory": { "index": 19, "kind": "parameter", "displayName": "Cache Loader Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.cache.configuration.Factory<javax.cache.integration.CacheLoader>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The CacheLoader factory" },
     "cacheWriterFactory": { "index": 20, "kind": "parameter", "displayName": "Cache Writer Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.cache.configuration.Factory<javax.cache.integration.CacheWriter>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "The CacheWriter factory" },
     "createCacheIfNotExists": { "index": 21, "kind": "parameter", "displayName": "Create Cache If Not Exists", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.jcache.JCacheConfiguration", "configurationField": "configuration", "description": "Configure if a cache need to be created if it does exist or can' [...]
diff --git a/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..c022d29e9c1
--- /dev/null
+++ b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=JCacheAggregationRepository JCacheIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-jcache
+version=4.5.0-SNAPSHOT
+projectName=Camel :: JCache
+projectDescription=Camel JCache support
diff --git a/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean/JCacheAggregationRepository.json b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean/JCacheAggregationRepository.json
new file mode 100644
index 00000000000..5a5cf747868
--- /dev/null
+++ b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean/JCacheAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "JCacheAggregationRepository",
+    "javaType": "org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "JCache Aggregation Repository",
+    "description": "Aggregation repository that uses JCache to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-jcache",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "configuration": { "index": 0, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Configuration for JCache" }, "optimistic": { "index": 1, "kind": "property", "displayName": "Optimistic", "required": false, "type": "object", "javaType": "org.apache.camel.componen [...]
+  }
+}
+
diff --git a/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean/JCacheIdempotentRepository.json b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean/JCacheIdempotentRepository.json
new file mode 100644
index 00000000000..76e7c1861cb
--- /dev/null
+++ b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/bean/JCacheIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "JCacheIdempotentRepository",
+    "javaType": "org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "JCache Idempotent Repository",
+    "description": "Idempotent repository that uses JCache to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-jcache",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "configuration": { "index": 0, "kind": "property", "displayName": "Configuration", "required": false, "type": "object", "javaType": "org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Configuration for JCache" } }
+  }
+}
+
diff --git a/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository
new file mode 100644
index 00000000000..7643a9336a8
--- /dev/null
+++ b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.jcache.processor.aggregate.JCacheAggregationRepositoryConfigurer
diff --git a/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository
new file mode 100644
index 00000000000..dd8d797f6b2
--- /dev/null
+++ b/components/camel-jcache/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.jcache.processor.idempotent.JCacheIdempotentRepositoryConfigurer
diff --git a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/JCacheConfiguration.java b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/JCacheConfiguration.java
index c8e93cbdc6f..db2a8a630bc 100644
--- a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/JCacheConfiguration.java
+++ b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/JCacheConfiguration.java
@@ -36,60 +36,43 @@ import org.apache.camel.support.EndpointHelper;
 
 @UriParams
 public class JCacheConfiguration {
+
     @UriParam(label = "common")
     private String cachingProvider;
-
-    @UriParam
+    @UriParam(label = "advanced")
     private Configuration cacheConfiguration;
-
     @UriParam
     private Properties cacheConfigurationProperties;
-
     @UriParam
     private String configurationUri;
-
     @UriParam(label = "advanced")
     private Factory<CacheLoader> cacheLoaderFactory;
-
     @UriParam(label = "advanced")
     private Factory<CacheWriter> cacheWriterFactory;
-
     @UriParam(label = "advanced")
     private Factory<ExpiryPolicy> expiryPolicyFactory;
-
     @UriParam
     private boolean readThrough;
-
     @UriParam
     private boolean writeThrough;
-
     @UriParam(defaultValue = "true")
     private boolean storeByValue = true;
-
     @UriParam
     private boolean statisticsEnabled;
-
     @UriParam
     private boolean managementEnabled;
-
     @UriParam(label = "consumer", enums = "CREATED,UPDATED,REMOVED,EXPIRED")
     private String filteredEvents;
-
     @UriParam(label = "consumer,advanced")
     private List<CacheEntryEventFilter> eventFilters;
-
     @UriParam(label = "consumer")
     private boolean oldValueRequired;
-
     @UriParam(label = "consumer")
     private boolean synchronous;
-
     @UriParam(label = "producer")
     private String action;
-
     @UriParam(label = "advanced", defaultValue = "true")
     private boolean createCacheIfNotExists = true;
-
     @UriParam(label = "advanced")
     private boolean lookupProviders;
 
diff --git a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/processor/aggregate/JCacheAggregationRepository.java b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/processor/aggregate/JCacheAggregationRepository.java
index 4bb33b18f1c..438c8866a47 100644
--- a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/processor/aggregate/JCacheAggregationRepository.java
+++ b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/processor/aggregate/JCacheAggregationRepository.java
@@ -29,6 +29,8 @@ import org.apache.camel.Exchange;
 import org.apache.camel.component.jcache.JCacheConfiguration;
 import org.apache.camel.component.jcache.JCacheHelper;
 import org.apache.camel.component.jcache.JCacheManager;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.OptimisticLockingAggregationRepository;
 import org.apache.camel.support.DefaultExchange;
 import org.apache.camel.support.DefaultExchangeHolder;
@@ -37,17 +39,26 @@ import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses JCache to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class JCacheAggregationRepository extends ServiceSupport
         implements CamelContextAware, OptimisticLockingAggregationRepository {
 
     private static final Logger LOG = LoggerFactory.getLogger(JCacheAggregationRepository.class);
 
     private CamelContext camelContext;
-    private JCacheConfiguration configuration;
     private Cache<String, DefaultExchangeHolder> cache;
+    private JCacheManager<String, DefaultExchangeHolder> cacheManager;
+
+    @Metadata(description = "Configuration for JCache")
+    private JCacheConfiguration configuration;
+    @Metadata(description = "Whether optimistic locking is in use")
     private boolean optimistic;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
     private boolean allowSerializedHeaders;
-    private JCacheManager<String, DefaultExchangeHolder> cacheManager;
 
     public JCacheAggregationRepository() {
         this.configuration = new JCacheConfiguration();
diff --git a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/processor/idempotent/JCacheIdempotentRepository.java b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/processor/idempotent/JCacheIdempotentRepository.java
index 8e9c8d56440..aef0069230b 100644
--- a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/processor/idempotent/JCacheIdempotentRepository.java
+++ b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/processor/idempotent/JCacheIdempotentRepository.java
@@ -26,17 +26,26 @@ import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.component.jcache.JCacheConfiguration;
 import org.apache.camel.component.jcache.JCacheHelper;
 import org.apache.camel.component.jcache.JCacheManager;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
 
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses JCache to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 @ManagedResource(description = "JCache based message id repository")
 public class JCacheIdempotentRepository extends ServiceSupport implements CamelContextAware, IdempotentRepository {
+
     private CamelContext camelContext;
-    private JCacheConfiguration configuration;
     private Cache<String, Boolean> cache;
     private JCacheManager<String, Boolean> cacheManager;
 
+    @Metadata(description = "Configuration for JCache")
+    private JCacheConfiguration configuration;
+
     public JCacheIdempotentRepository() {
         this.configuration = new JCacheConfiguration();
     }
@@ -120,6 +129,8 @@ public class JCacheIdempotentRepository extends ServiceSupport implements CamelC
 
     @Override
     protected void doStop() throws Exception {
-        cacheManager.close();
+        if (cacheManager != null) {
+            cacheManager.close();
+        }
     }
 }
diff --git a/components/camel-kafka/src/generated/java/org/apache/camel/processor/idempotent/kafka/KafkaIdempotentRepositoryConfigurer.java b/components/camel-kafka/src/generated/java/org/apache/camel/processor/idempotent/kafka/KafkaIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..f225adbc76c
--- /dev/null
+++ b/components/camel-kafka/src/generated/java/org/apache/camel/processor/idempotent/kafka/KafkaIdempotentRepositoryConfigurer.java
@@ -0,0 +1,67 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.idempotent.kafka;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class KafkaIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository target = (org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "bootstrapservers":
+        case "BootstrapServers": target.setBootstrapServers(property(camelContext, java.lang.String.class, value)); return true;
+        case "maxcachesize":
+        case "MaxCacheSize": target.setMaxCacheSize(property(camelContext, int.class, value)); return true;
+        case "polldurationms":
+        case "PollDurationMs": target.setPollDurationMs(property(camelContext, int.class, value)); return true;
+        case "topic":
+        case "Topic": target.setTopic(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "bootstrapservers":
+        case "BootstrapServers": return java.lang.String.class;
+        case "maxcachesize":
+        case "MaxCacheSize": return int.class;
+        case "polldurationms":
+        case "PollDurationMs": return int.class;
+        case "topic":
+        case "Topic": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository target = (org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "bootstrapservers":
+        case "BootstrapServers": return target.getBootstrapServers();
+        case "maxcachesize":
+        case "MaxCacheSize": return target.getMaxCacheSize();
+        case "polldurationms":
+        case "PollDurationMs": return target.getPollDurationMs();
+        case "topic":
+        case "Topic": return target.getTopic();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..b41892c0c07
--- /dev/null
+++ b/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=KafkaIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-kafka
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Kafka
+projectDescription=Camel Kafka support
diff --git a/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/bean/KafkaIdempotentRepository.json b/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/bean/KafkaIdempotentRepository.json
new file mode 100644
index 00000000000..ef73b04be6c
--- /dev/null
+++ b/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/bean/KafkaIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "KafkaIdempotentRepository",
+    "javaType": "org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Kafka Idempotent Repository",
+    "description": "Idempotent repository that uses Kafka to store message ids. Uses a local cache of previously seen Message IDs. The topic used must be unique per logical repository (i.e. two routes de-duplicate using different repositories, and different topics) On startup, the instance consumes the full content of the topic, rebuilding the cache to the latest state.",
+    "deprecated": true,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-kafka",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "topic": { "index": 0, "kind": "property", "displayName": "Topic", "required": true, "type": "object", "javaType": "org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the name of the Kafka topic used by this idempotent repository. Each functionally-separate repository should use a different topic." }, "bootstrapServers": { "index": 1, "kind": "property", "displayName":  [...]
+  }
+}
+
diff --git a/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository b/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository
new file mode 100644
index 00000000000..ca18523d286
--- /dev/null
+++ b/components/camel-kafka/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.idempotent.kafka.KafkaIdempotentRepositoryConfigurer
diff --git a/components/camel-kafka/src/main/java/org/apache/camel/processor/idempotent/kafka/KafkaIdempotentRepository.java b/components/camel-kafka/src/main/java/org/apache/camel/processor/idempotent/kafka/KafkaIdempotentRepository.java
index fafcfed61bc..b5ce20da233 100644
--- a/components/camel-kafka/src/main/java/org/apache/camel/processor/idempotent/kafka/KafkaIdempotentRepository.java
+++ b/components/camel-kafka/src/main/java/org/apache/camel/processor/idempotent/kafka/KafkaIdempotentRepository.java
@@ -29,7 +29,9 @@ import org.apache.camel.CamelContextAware;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.LRUCacheFactory;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.IOHelper;
@@ -64,40 +66,57 @@ import org.slf4j.LoggerFactory;
  * must be placed in the Camel registry, either manually or by registration as a bean in Spring/Blueprint, as it is
  * CamelContext aware.
  */
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses Kafka to store message ids. Uses a local cache of previously seen Message IDs."
+                        + " The topic used must be unique per logical repository (i.e. two routes de-duplicate using different repositories, and different topics)"
+                        + " On startup, the instance consumes the full content of the topic, rebuilding the cache to the latest state.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 @ManagedResource(description = "Kafka IdempotentRepository")
 public class KafkaIdempotentRepository extends ServiceSupport implements IdempotentRepository, CamelContextAware {
 
+    private static final Logger LOG = LoggerFactory.getLogger(KafkaIdempotentRepository.class);
+
     private static final int DEFAULT_MAXIMUM_CACHE_SIZE = 1000;
     private static final int DEFAULT_POLL_DURATION_MS = 100;
 
-    private final Logger log = LoggerFactory.getLogger(this.getClass());
+    private CamelContext camelContext;
+    // internal properties
+    private Map<String, Object> cache;
+    private Consumer<String, String> consumer;
+    private Producer<String, String> producer;
+
+    private Properties producerConfig;
+    private Properties consumerConfig;
+    private String groupId; // not in use
 
     // configurable
+    @Metadata(description = "Sets the name of the Kafka topic used by this idempotent repository."
+                            + " Each functionally-separate repository should use a different topic.",
+              required = true)
     private String topic;
+    @Metadata(description = "The URL for the kafka brokers to use", required = true)
     private String bootstrapServers;
-
-    private String groupId;
-    private Properties producerConfig;
-    private Properties consumerConfig;
+    @Metadata(description = "Sets the maximum size of the local key cache.", defaultValue = "" + DEFAULT_MAXIMUM_CACHE_SIZE)
     private int maxCacheSize = DEFAULT_MAXIMUM_CACHE_SIZE;
+    @Metadata(description = "Sets the poll duration of the Kafka consumer. The local caches are updated immediately; this value will affect"
+                            + " how far behind other peers in the cluster are, which are updating their caches from the topic, relative to the"
+                            + " idempotent consumer instance issued the cache action message. The default value of this is 100"
+                            + " If setting this value explicitly, be aware that there is a tradeoff between"
+                            + " the remote cache liveness and the volume of network traffic between this repository's consumer and the Kafka"
+                            + " brokers. The cache warmup process also depends on there being one poll that fetches nothing - this indicates that"
+                            + " the stream has been consumed up to the current point. If the poll duration is excessively long for the rate at"
+                            + " which messages are sent on the topic, there exists a possibility that the cache cannot be warmed up and will"
+                            + " operate in an inconsistent state relative to its peers until it catches up.",
+              defaultValue = "" + DEFAULT_POLL_DURATION_MS)
     private int pollDurationMs = DEFAULT_POLL_DURATION_MS;
 
-    // internal properties
-    private Map<String, Object> cache;
-    private Consumer<String, String> consumer;
-    private Producer<String, String> producer;
-
-    private CamelContext camelContext;
-
     enum CacheAction {
         add,
         remove,
         clear
     }
 
-    /**
-     * No-op constructor for XML/property-based object initialisation. From Java, prefer one of the other constructors.
-     */
     public KafkaIdempotentRepository() {
     }
 
@@ -187,23 +206,9 @@ public class KafkaIdempotentRepository extends ServiceSupport implements Idempot
     }
 
     /**
-     * Sets the
-     *
-     * <pre>
-     * bootstrap.servers
-     * </pre>
-     *
-     * property on the internal Kafka producer and consumer. Use this as shorthand if not setting
-     * {@link #consumerConfig} and {@link #producerConfig}. If used, this component will apply sensible default
+     * Sets the bootstrap.servers property on the internal Kafka producer and consumer. Use this as shorthand if not
+     * setting {@link #consumerConfig} and {@link #producerConfig}. If used, this component will apply sensible default
      * configurations for the producer and consumer.
-     *
-     * @param bootstrapServers The
-     *
-     *                         <pre>
-     *                         bootstrap.servers
-     *                         </pre>
-     *
-     *                         value to use.
      */
     public void setBootstrapServers(String bootstrapServers) {
         this.bootstrapServers = bootstrapServers;
@@ -354,20 +359,20 @@ public class KafkaIdempotentRepository extends ServiceSupport implements Idempot
     }
 
     private void populateCache() {
-        log.debug("Getting partitions of topic {}", topic);
+        LOG.debug("Getting partitions of topic {}", topic);
         List<PartitionInfo> partitionInfos = consumer.partitionsFor(topic);
         Collection<TopicPartition> partitions = partitionInfos.stream()
                 .map(pi -> new TopicPartition(pi.topic(), pi.partition()))
                 .collect(Collectors.toUnmodifiableList());
 
-        log.debug("Assigning consumer to partitions {}", partitions);
+        LOG.debug("Assigning consumer to partitions {}", partitions);
         consumer.assign(partitions);
 
-        log.debug("Seeking consumer to beginning of partitions {}", partitions);
+        LOG.debug("Seeking consumer to beginning of partitions {}", partitions);
         consumer.seekToBeginning(partitions);
 
         Map<TopicPartition, Long> endOffsets = consumer.endOffsets(partitions);
-        log.debug("Consuming records from partitions {} till end offsets {}", partitions, endOffsets);
+        LOG.debug("Consuming records from partitions {} till end offsets {}", partitions, endOffsets);
         while (!KafkaConsumerUtil.isReachedOffsets(consumer, endOffsets)) {
             ConsumerRecords<String, String> consumerRecords = consumer.poll(Duration.ofMillis(pollDurationMs));
             for (ConsumerRecord<String, String> consumerRecord : consumerRecords) {
@@ -382,17 +387,17 @@ public class KafkaIdempotentRepository extends ServiceSupport implements Idempot
         try {
             action = CacheAction.valueOf(consumerRecord.value());
         } catch (IllegalArgumentException iax) {
-            log.error(
+            LOG.error(
                     "Unexpected action value:\"{}\" received on [topic:{}, partition:{}, offset:{}]. Shutting down.",
                     consumerRecord.key(), consumerRecord.topic(),
                     consumerRecord.partition(), consumerRecord.offset());
         }
         String messageId = consumerRecord.key();
         if (action == CacheAction.add) {
-            log.debug("Adding to cache messageId:{}", messageId);
+            LOG.debug("Adding to cache messageId:{}", messageId);
             cache.put(messageId, messageId);
         } else if (action == CacheAction.remove) {
-            log.debug("Removing from cache messageId:{}", messageId);
+            LOG.debug("Removing from cache messageId:{}", messageId);
             cache.remove(messageId);
         } else if (action == CacheAction.clear) {
             cache.clear();
@@ -404,8 +409,8 @@ public class KafkaIdempotentRepository extends ServiceSupport implements Idempot
 
     @Override
     protected void doStop() {
-        IOHelper.close(consumer, "consumer", log);
-        IOHelper.close(producer, "producer", log);
+        IOHelper.close(consumer, "consumer", LOG);
+        IOHelper.close(producer, "producer", LOG);
     }
 
     @Override
@@ -424,7 +429,7 @@ public class KafkaIdempotentRepository extends ServiceSupport implements Idempot
 
     private void broadcastAction(String key, CacheAction action) {
         try {
-            log.debug("Broadcasting action:{} for key:{}", action, key);
+            LOG.debug("Broadcasting action:{} for key:{}", action, key);
             ObjectHelper.notNull(producer, "producer");
 
             producer.send(new ProducerRecord<>(topic, key, action.toString())).get(); // sync send
@@ -439,7 +444,7 @@ public class KafkaIdempotentRepository extends ServiceSupport implements Idempot
     @Override
     @ManagedOperation(description = "Does the store contain the given key")
     public boolean contains(String key) {
-        log.debug("Checking cache for key:{}", key);
+        LOG.debug("Checking cache for key:{}", key);
         return cache.containsKey(key);
     }
 
diff --git a/components/camel-leveldb/src/generated/java/org/apache/camel/component/leveldb/LevelDBAggregationRepositoryConfigurer.java b/components/camel-leveldb/src/generated/java/org/apache/camel/component/leveldb/LevelDBAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..4cabaaba87b
--- /dev/null
+++ b/components/camel-leveldb/src/generated/java/org/apache/camel/component/leveldb/LevelDBAggregationRepositoryConfigurer.java
@@ -0,0 +1,103 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.leveldb;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.leveldb.LevelDBAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class LevelDBAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.leveldb.LevelDBAggregationRepository target = (org.apache.camel.component.leveldb.LevelDBAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "persistentfilename":
+        case "PersistentFileName": target.setPersistentFileName(property(camelContext, java.lang.String.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "repositoryname":
+        case "RepositoryName": target.setRepositoryName(property(camelContext, java.lang.String.class, value)); return true;
+        case "returnoldexchange":
+        case "ReturnOldExchange": target.setReturnOldExchange(property(camelContext, boolean.class, value)); return true;
+        case "serializer":
+        case "Serializer": target.setSerializer(property(camelContext, org.apache.camel.component.leveldb.LevelDBSerializer.class, value)); return true;
+        case "sync":
+        case "Sync": target.setSync(property(camelContext, boolean.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "persistentfilename":
+        case "PersistentFileName": return java.lang.String.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "repositoryname":
+        case "RepositoryName": return java.lang.String.class;
+        case "returnoldexchange":
+        case "ReturnOldExchange": return boolean.class;
+        case "serializer":
+        case "Serializer": return org.apache.camel.component.leveldb.LevelDBSerializer.class;
+        case "sync":
+        case "Sync": return boolean.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.leveldb.LevelDBAggregationRepository target = (org.apache.camel.component.leveldb.LevelDBAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "persistentfilename":
+        case "PersistentFileName": return target.getPersistentFileName();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "repositoryname":
+        case "RepositoryName": return target.getRepositoryName();
+        case "returnoldexchange":
+        case "ReturnOldExchange": return target.isReturnOldExchange();
+        case "serializer":
+        case "Serializer": return target.getSerializer();
+        case "sync":
+        case "Sync": return target.isSync();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..6937dba2de8
--- /dev/null
+++ b/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=LevelDBAggregationRepository
+groupId=org.apache.camel
+artifactId=camel-leveldb
+version=4.5.0-SNAPSHOT
+projectName=Camel :: LevelDB
+projectDescription=Using LevelDB as persistent EIP store
diff --git a/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean/LevelDBAggregationRepository.json b/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean/LevelDBAggregationRepository.json
new file mode 100644
index 00000000000..43bc883d6a5
--- /dev/null
+++ b/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/bean/LevelDBAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "LevelDBAggregationRepository",
+    "javaType": "org.apache.camel.component.leveldb.LevelDBAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Level DBAggregation Repository",
+    "description": "Aggregation repository that uses LevelDB to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-leveldb",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "persistentFileName": { "index": 0, "kind": "property", "displayName": "Persistent File Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.leveldb.LevelDBAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of file to use for storing data" }, "repositoryName": { "index": 1, "kind": "property", "displayName": "Repository Name", "required": true, "type": "object", "javaType": "org.apache.c [...]
+  }
+}
+
diff --git a/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.leveldb.LevelDBAggregationRepository b/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.leveldb.LevelDBAggregationRepository
new file mode 100644
index 00000000000..d1425716ce4
--- /dev/null
+++ b/components/camel-leveldb/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.leveldb.LevelDBAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.leveldb.LevelDBAggregationRepositoryConfigurer
diff --git a/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBAggregationRepository.java b/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBAggregationRepository.java
index c4643b63d1d..20bfb3e86f1 100644
--- a/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBAggregationRepository.java
+++ b/components/camel-leveldb/src/main/java/org/apache/camel/component/leveldb/LevelDBAggregationRepository.java
@@ -26,6 +26,8 @@ import java.util.concurrent.TimeUnit;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.support.service.ServiceSupport;
@@ -40,21 +42,40 @@ import org.slf4j.LoggerFactory;
 /**
  * An instance of {@link org.apache.camel.spi.AggregationRepository} which is backed by a {@link LevelDBFile}.
  */
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses LevelDB to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class LevelDBAggregationRepository extends ServiceSupport implements RecoverableAggregationRepository {
 
     private static final Logger LOG = LoggerFactory.getLogger(LevelDBAggregationRepository.class);
 
     private LevelDBFile levelDBFile;
+    private LevelDBCamelCodec codec;
+
+    @Metadata(description = "Name of file to use for storing data", required = true)
     private String persistentFileName;
+    @Metadata(description = "Name of repository", required = true)
     private String repositoryName;
+    @Metadata(description = "Whether LevelDB should sync writes")
     private boolean sync;
+    @Metadata(label = "advanced",
+              description = "Whether to return the old exchange when adding new exchanges to the repository")
     private boolean returnOldExchange;
-    private LevelDBCamelCodec codec;
-    private long recoveryInterval = 5000;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
     private boolean useRecovery = true;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
+    private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.")
     private int maximumRedeliveries;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
     private String deadLetterUri;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
     private boolean allowSerializedHeaders;
+    @Metadata(label = "advanced",
+              description = "To use a custom serializer for LevelDB")
     private LevelDBSerializer serializer;
 
     /**
@@ -361,13 +382,13 @@ public class LevelDBAggregationRepository extends ServiceSupport implements Reco
     }
 
     @Override
-    public void setRecoveryInterval(long interval) {
-        this.recoveryInterval = interval;
+    public long getRecoveryInterval() {
+        return recoveryInterval;
     }
 
     @Override
-    public long getRecoveryIntervalInMillis() {
-        return recoveryInterval;
+    public void setRecoveryInterval(long interval) {
+        this.recoveryInterval = interval;
     }
 
     @Override
diff --git a/components/camel-mongodb/src/generated/java/org/apache/camel/component/mongodb/processor/idempotent/MongoDbIdempotentRepositoryConfigurer.java b/components/camel-mongodb/src/generated/java/org/apache/camel/component/mongodb/processor/idempotent/MongoDbIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..f4fb3f07d34
--- /dev/null
+++ b/components/camel-mongodb/src/generated/java/org/apache/camel/component/mongodb/processor/idempotent/MongoDbIdempotentRepositoryConfigurer.java
@@ -0,0 +1,61 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.mongodb.processor.idempotent;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class MongoDbIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository target = (org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "collectionname":
+        case "CollectionName": target.setCollectionName(property(camelContext, java.lang.String.class, value)); return true;
+        case "dbname":
+        case "DbName": target.setDbName(property(camelContext, java.lang.String.class, value)); return true;
+        case "mongoclient":
+        case "MongoClient": target.setMongoClient(property(camelContext, com.mongodb.client.MongoClient.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "collectionname":
+        case "CollectionName": return java.lang.String.class;
+        case "dbname":
+        case "DbName": return java.lang.String.class;
+        case "mongoclient":
+        case "MongoClient": return com.mongodb.client.MongoClient.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository target = (org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "collectionname":
+        case "CollectionName": return target.getCollectionName();
+        case "dbname":
+        case "DbName": return target.getDbName();
+        case "mongoclient":
+        case "MongoClient": return target.getMongoClient();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..ed153d6739c
--- /dev/null
+++ b/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=MongoDbIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-mongodb
+version=4.5.0-SNAPSHOT
+projectName=Camel :: MongoDB
+projectDescription=Camel MongoDB (Java Driver 3) component
diff --git a/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/bean/MongoDbIdempotentRepository.json b/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/bean/MongoDbIdempotentRepository.json
new file mode 100644
index 00000000000..749f99167b9
--- /dev/null
+++ b/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/bean/MongoDbIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "MongoDbIdempotentRepository",
+    "javaType": "org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Mongo Db Idempotent Repository",
+    "description": "Idempotent repository that uses MongoDB to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-mongodb",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "mongoClient": { "index": 0, "kind": "property", "displayName": "Mongo Client", "required": true, "type": "object", "javaType": "org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "The MongoClient to use for connecting to the MongoDB server" }, "dbName": { "index": 1, "kind": "property", "displayName": "Db Name", "required": true, "type": "object", "javaType": " [...]
+  }
+}
+
diff --git a/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository b/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository
new file mode 100644
index 00000000000..c192d4e00dc
--- /dev/null
+++ b/components/camel-mongodb/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.mongodb.processor.idempotent.MongoDbIdempotentRepositoryConfigurer
diff --git a/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/processor/idempotent/MongoDbIdempotentRepository.java b/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/processor/idempotent/MongoDbIdempotentRepository.java
index 9e450aae0f1..7056c9b2cc5 100644
--- a/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/processor/idempotent/MongoDbIdempotentRepository.java
+++ b/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/processor/idempotent/MongoDbIdempotentRepository.java
@@ -22,7 +22,9 @@ import com.mongodb.client.MongoCollection;
 import com.mongodb.client.result.DeleteResult;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
 import org.bson.Document;
@@ -31,11 +33,20 @@ import org.bson.conversions.Bson;
 import static com.mongodb.client.model.Filters.eq;
 import static org.apache.camel.component.mongodb.MongoDbConstants.MONGO_ID;
 
-@ManagedResource(description = "Mongo db based message id repository")
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses MongoDB to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
+@ManagedResource(description = "MongoDB based message id repository")
 public class MongoDbIdempotentRepository extends ServiceSupport implements IdempotentRepository {
+
+    @Metadata(description = "The MongoClient to use for connecting to the MongoDB server", required = true)
     private MongoClient mongoClient;
-    private String collectionName;
+    @Metadata(description = "The Database name", required = true)
     private String dbName;
+    @Metadata(description = "The collection name", required = true)
+    private String collectionName;
+
     private MongoCollection<Document> collection;
 
     public MongoDbIdempotentRepository() {
@@ -45,7 +56,6 @@ public class MongoDbIdempotentRepository extends ServiceSupport implements Idemp
         this.mongoClient = mongoClient;
         this.collectionName = collectionName;
         this.dbName = dbName;
-        this.collection = mongoClient.getDatabase(dbName).getCollection(collectionName);
     }
 
     @ManagedOperation(description = "Adds the key to the store")
@@ -103,7 +113,7 @@ public class MongoDbIdempotentRepository extends ServiceSupport implements Idemp
 
     @Override
     protected void doStop() throws Exception {
-        return;
+        // noop
     }
 
     public MongoClient getMongoClient() {
diff --git a/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/processor/idempotent/integration/MongoDbIdempotentRepositoryIT.java b/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/processor/idempotent/integration/MongoDbIdempotentRepositoryIT.java
index f10be3621e4..7bb11601ac9 100644
--- a/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/processor/idempotent/integration/MongoDbIdempotentRepositoryIT.java
+++ b/components/camel-mongodb/src/test/java/org/apache/camel/component/mongodb/processor/idempotent/integration/MongoDbIdempotentRepositoryIT.java
@@ -42,6 +42,7 @@ public class MongoDbIdempotentRepositoryIT extends AbstractMongoDbITSupport {
     @BeforeEach
     public void setupIdempotentRepository() {
         repo = new MongoDbIdempotentRepository(mongo, testCollectionName, dbName);
+        repo.start();
     }
 
     @Test
diff --git a/components/camel-opensearch/src/generated/java/org/apache/camel/component/opensearch/aggregation/OpensearchBulkRequestAggregationStrategyConfigurer.java b/components/camel-opensearch/src/generated/java/org/apache/camel/component/opensearch/aggregation/OpensearchBulkRequestAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..da60f6d19dd
--- /dev/null
+++ b/components/camel-opensearch/src/generated/java/org/apache/camel/component/opensearch/aggregation/OpensearchBulkRequestAggregationStrategyConfigurer.java
@@ -0,0 +1,35 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.opensearch.aggregation;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.opensearch.aggregation.OpensearchBulkRequestAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class OpensearchBulkRequestAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git a/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..7fe4a21c327
--- /dev/null
+++ b/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=OpensearchBulkRequestAggregationStrategy
+groupId=org.apache.camel
+artifactId=camel-opensearch
+version=4.5.0-SNAPSHOT
+projectName=Camel :: OpenSearch Java API Client
+projectDescription=Camel OpenSearch Java API Client support
diff --git a/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/bean/OpensearchBulkRequestAggregationStrategy.json b/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/bean/OpensearchBulkRequestAggregationStrategy.json
new file mode 100644
index 00000000000..482106ac075
--- /dev/null
+++ b/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/bean/OpensearchBulkRequestAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "OpensearchBulkRequestAggregationStrategy",
+    "javaType": "org.apache.camel.component.opensearch.aggregation.OpensearchBulkRequestAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Opensearch Bulk Request Aggregation Strategy",
+    "description": "Aggregates two OpenSearch BulkOperation into a single BulkRequest",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-opensearch",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.opensearch.aggregation.OpensearchBulkRequestAggregationStrategy b/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.opensearch.aggregation.OpensearchBulkRequestAggregationStrategy
new file mode 100644
index 00000000000..8f96f068050
--- /dev/null
+++ b/components/camel-opensearch/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.opensearch.aggregation.OpensearchBulkRequestAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.opensearch.aggregation.OpensearchBulkRequestAggregationStrategyConfigurer
diff --git a/components/camel-opensearch/src/main/java/org/apache/camel/component/opensearch/aggregation/BulkRequestAggregationStrategy.java b/components/camel-opensearch/src/main/java/org/apache/camel/component/opensearch/aggregation/OpensearchBulkRequestAggregationStrategy.java
similarity index 83%
rename from components/camel-opensearch/src/main/java/org/apache/camel/component/opensearch/aggregation/BulkRequestAggregationStrategy.java
rename to components/camel-opensearch/src/main/java/org/apache/camel/component/opensearch/aggregation/OpensearchBulkRequestAggregationStrategy.java
index 40e109e8631..c475792dde5 100644
--- a/components/camel-opensearch/src/main/java/org/apache/camel/component/opensearch/aggregation/BulkRequestAggregationStrategy.java
+++ b/components/camel-opensearch/src/main/java/org/apache/camel/component/opensearch/aggregation/OpensearchBulkRequestAggregationStrategy.java
@@ -21,13 +21,19 @@ import java.util.List;
 import org.apache.camel.AggregationStrategy;
 import org.apache.camel.Exchange;
 import org.apache.camel.InvalidPayloadRuntimeException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.opensearch.client.opensearch.core.BulkRequest;
 import org.opensearch.client.opensearch.core.bulk.BulkOperation;
 
 /**
  * Aggregates two {@link BulkOperation}s into a single {@link BulkRequest}.
  */
-public class BulkRequestAggregationStrategy implements AggregationStrategy {
+@Metadata(label = "bean",
+          description = "Aggregates two OpenSearch BulkOperation into a single BulkRequest",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
+public class OpensearchBulkRequestAggregationStrategy implements AggregationStrategy {
 
     @Override
     public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
diff --git a/components/camel-redis/src/main/java/org/apache/camel/component/redis/processor/aggregate/RedisAggregationRepository.java b/components/camel-redis/src/main/java/org/apache/camel/component/redis/processor/aggregate/RedisAggregationRepository.java
index c8e536c5846..8ebd1c0a233 100644
--- a/components/camel-redis/src/main/java/org/apache/camel/component/redis/processor/aggregate/RedisAggregationRepository.java
+++ b/components/camel-redis/src/main/java/org/apache/camel/component/redis/processor/aggregate/RedisAggregationRepository.java
@@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.OptimisticLockingAggregationRepository;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.DefaultExchange;
@@ -47,18 +48,32 @@ public class RedisAggregationRepository extends ServiceSupport
     private static final Logger LOG = LoggerFactory.getLogger(RedisAggregationRepository.class);
     private static final String COMPLETED_SUFFIX = "-completed";
 
-    private boolean optimistic;
-    private boolean useRecovery = true;
     private Map<String, DefaultExchangeHolder> cache;
     private Map<String, DefaultExchangeHolder> persistedCache;
+    private boolean shutdownRedisson;
+
+    @Metadata(label = "advanced", description = "To use an existing Redis client to connect to Redis server")
+    private RedissonClient redisson;
+    @Metadata(description = "URL to remote Redis server", required = true)
     private String endpoint;
+    @Metadata(description = "Name of cache to use", required = true)
     private String mapName;
+    @Metadata(label = "advanced", description = "Name of cache to use for completed exchanges")
     private String persistenceMapName;
-    private RedissonClient redisson;
-    private boolean shutdownRedisson;
-    private String deadLetterChannel;
+    @Metadata(description = "Whether optimistic locking is in use")
+    private boolean optimistic;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
+    private boolean useRecovery = true;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
+    private String deadLetterUri;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
     private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.",
+              defaultValue = "3")
     private int maximumRedeliveries = 3;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
     private boolean allowSerializedHeaders;
 
     public RedisAggregationRepository() {
@@ -206,13 +221,13 @@ public class RedisAggregationRepository extends ServiceSupport
     }
 
     @Override
-    public void setRecoveryInterval(long interval) {
-        this.recoveryInterval = interval;
+    public long getRecoveryInterval() {
+        return recoveryInterval;
     }
 
     @Override
-    public long getRecoveryIntervalInMillis() {
-        return recoveryInterval;
+    public void setRecoveryInterval(long interval) {
+        this.recoveryInterval = interval;
     }
 
     @Override
@@ -227,12 +242,12 @@ public class RedisAggregationRepository extends ServiceSupport
 
     @Override
     public void setDeadLetterUri(String deadLetterUri) {
-        this.deadLetterChannel = deadLetterUri;
+        this.deadLetterUri = deadLetterUri;
     }
 
     @Override
     public String getDeadLetterUri() {
-        return deadLetterChannel;
+        return deadLetterUri;
     }
 
     @Override
@@ -355,6 +370,9 @@ public class RedisAggregationRepository extends ServiceSupport
 
     @Override
     protected void doStart() throws Exception {
+        if (persistenceMapName == null) {
+            persistenceMapName = String.format("%s%s", mapName, COMPLETED_SUFFIX);
+        }
         if (redisson == null) {
             Config config = new Config();
             config.useSingleServer().setAddress(String.format("redis://%s", endpoint));
diff --git a/components/camel-spring-redis/src/generated/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepositoryConfigurer.java b/components/camel-spring-redis/src/generated/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..4ef35e3ec95
--- /dev/null
+++ b/components/camel-spring-redis/src/generated/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepositoryConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.redis.processor.idempotent;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class SpringRedisIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository target = (org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "repositoryname":
+        case "RepositoryName": target.setRepositoryName(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "repositoryname":
+        case "RepositoryName": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository target = (org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "repositoryname":
+        case "RepositoryName": return target.getRepositoryName();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..84b1b22f068
--- /dev/null
+++ b/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=SpringRedisIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-spring-redis
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Redis
+projectDescription=Camel Spring Redis Component
diff --git a/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/bean/SpringRedisIdempotentRepository.json b/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/bean/SpringRedisIdempotentRepository.json
new file mode 100644
index 00000000000..a47bd531d89
--- /dev/null
+++ b/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/bean/SpringRedisIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "SpringRedisIdempotentRepository",
+    "javaType": "org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Spring Redis Idempotent Repository",
+    "description": "Idempotent repository that uses Redis to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-spring-redis",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "repositoryName": { "index": 0, "kind": "property", "displayName": "Repository Name", "required": true, "type": "object", "javaType": "org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Name of repository" }, "redisConfiguration": { "index": 1, "kind": "property", "displayName": "Redis Configuration", "required": false, "type": "object", "javaType": "org.apac [...]
+  }
+}
+
diff --git a/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository b/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository
new file mode 100644
index 00000000000..b5f65f01571
--- /dev/null
+++ b/components/camel-spring-redis/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepositoryConfigurer
diff --git a/components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/RedisIdempotentRepository.java b/components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepository.java
similarity index 62%
rename from components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/RedisIdempotentRepository.java
rename to components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepository.java
index 9f9f869150d..361e1b71943 100644
--- a/components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/RedisIdempotentRepository.java
+++ b/components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepository.java
@@ -20,46 +20,54 @@ import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.component.redis.RedisConfiguration;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.service.ServiceSupport;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.SetOperations;
 
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses Redis to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 @ManagedResource(description = "Spring Redis based message id repository")
-public class RedisIdempotentRepository extends ServiceSupport implements IdempotentRepository {
-    private final SetOperations<String, String> setOperations;
-    private final String processorName;
+public class SpringRedisIdempotentRepository extends ServiceSupport implements IdempotentRepository {
+
+    private SetOperations<String, String> setOperations;
+    @Metadata(description = "Name of repository", required = true)
+    private String repositoryName;
+    @Metadata(description = "Redis configuration")
     private RedisConfiguration redisConfiguration;
     private RedisTemplate<String, String> redisTemplate;
 
-    public RedisIdempotentRepository(RedisTemplate<String, String> redisTemplate, String processorName) {
+    public SpringRedisIdempotentRepository() {
+    }
+
+    public SpringRedisIdempotentRepository(RedisTemplate<String, String> redisTemplate, String repositoryName) {
         this.setOperations = redisTemplate.opsForSet();
-        this.processorName = processorName;
+        this.repositoryName = repositoryName;
         this.redisTemplate = redisTemplate;
     }
 
-    public RedisIdempotentRepository(String processorName) {
-        redisConfiguration = new RedisConfiguration();
-        this.redisTemplate = (RedisTemplate<String, String>) redisConfiguration.getRedisTemplate();
-        this.setOperations = redisTemplate.opsForSet();
-        redisTemplate.getConnectionFactory().getConnection().flushDb();
-        this.processorName = processorName;
+    public SpringRedisIdempotentRepository(String repositoryName) {
+        this.repositoryName = repositoryName;
     }
 
-    public static RedisIdempotentRepository redisIdempotentRepository(String processorName) {
-        return new RedisIdempotentRepository(processorName);
+    public static SpringRedisIdempotentRepository redisIdempotentRepository(String processorName) {
+        return new SpringRedisIdempotentRepository(processorName);
     }
 
-    public static RedisIdempotentRepository redisIdempotentRepository(
+    public static SpringRedisIdempotentRepository redisIdempotentRepository(
             RedisTemplate<String, String> redisTemplate, String processorName) {
-        return new RedisIdempotentRepository(redisTemplate, processorName);
+        return new SpringRedisIdempotentRepository(redisTemplate, processorName);
     }
 
     @Override
     @ManagedOperation(description = "Adds the key to the store")
     public boolean add(String key) {
         if (!contains(key)) {
-            return setOperations.add(processorName, key) != null;
+            return setOperations.add(repositoryName, key) != null;
         } else {
             return false;
         }
@@ -68,13 +76,13 @@ public class RedisIdempotentRepository extends ServiceSupport implements Idempot
     @Override
     @ManagedOperation(description = "Does the store contain the given key")
     public boolean contains(String key) {
-        return setOperations.isMember(processorName, key);
+        return setOperations.isMember(repositoryName, key);
     }
 
     @Override
     @ManagedOperation(description = "Remove the key from the store")
     public boolean remove(String key) {
-        return setOperations.remove(processorName, key) != null;
+        return setOperations.remove(repositoryName, key) != null;
     }
 
     @Override
@@ -83,9 +91,13 @@ public class RedisIdempotentRepository extends ServiceSupport implements Idempot
         redisTemplate.getConnectionFactory().getConnection().flushDb();
     }
 
-    @ManagedAttribute(description = "The processor name")
-    public String getProcessorName() {
-        return processorName;
+    public void setRepositoryName(String repositoryName) {
+        this.repositoryName = repositoryName;
+    }
+
+    @ManagedAttribute(description = "The repository name")
+    public String getRepositoryName() {
+        return repositoryName;
     }
 
     @Override
@@ -95,7 +107,12 @@ public class RedisIdempotentRepository extends ServiceSupport implements Idempot
 
     @Override
     protected void doStart() throws Exception {
-        // noop
+        if (redisConfiguration == null) {
+            redisConfiguration = new RedisConfiguration();
+        }
+        this.redisTemplate = (RedisTemplate<String, String>) redisConfiguration.getRedisTemplate();
+        this.setOperations = redisTemplate.opsForSet();
+        redisTemplate.getConnectionFactory().getConnection().flushDb();
     }
 
     @Override
diff --git a/components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepository.java b/components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisStringIdempotentRepository.java
similarity index 93%
rename from components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepository.java
rename to components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisStringIdempotentRepository.java
index 953fdcea42d..647d3365886 100644
--- a/components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepository.java
+++ b/components/camel-spring-redis/src/main/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisStringIdempotentRepository.java
@@ -31,13 +31,13 @@ import org.springframework.data.redis.core.ScanOptions;
 import org.springframework.data.redis.core.ValueOperations;
 
 @ManagedResource(description = "Spring Redis based message id repository")
-public class RedisStringIdempotentRepository extends RedisIdempotentRepository {
+public class SpringRedisStringIdempotentRepository extends SpringRedisIdempotentRepository {
 
     private final ValueOperations<String, String> valueOperations;
 
     private long expiry;
 
-    public RedisStringIdempotentRepository(RedisTemplate<String, String> redisTemplate, String processorName) {
+    public SpringRedisStringIdempotentRepository(RedisTemplate<String, String> redisTemplate, String processorName) {
         super(redisTemplate, processorName);
         this.valueOperations = redisTemplate.opsForValue();
     }
@@ -87,7 +87,7 @@ public class RedisStringIdempotentRepository extends RedisIdempotentRepository {
     }
 
     protected String createRedisKey(String key) {
-        return getProcessorName() + ":" + key;
+        return getRepositoryName() + ":" + key;
     }
 
     public long getExpiry() {
diff --git a/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepositoryManualIT.java b/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepositoryManualIT.java
index a8a9862a36b..e007ba287f0 100644
--- a/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepositoryManualIT.java
+++ b/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepositoryManualIT.java
@@ -41,7 +41,7 @@ public class RedisStringIdempotentRepositoryManualIT extends CamelTestSupport {
 
     private static final JedisConnectionFactory CONNECTION_FACTORY = new JedisConnectionFactory();
 
-    protected RedisStringIdempotentRepository idempotentRepository;
+    protected SpringRedisStringIdempotentRepository idempotentRepository;
 
     @Produce("direct:start")
     private ProducerTemplate producer;
@@ -69,7 +69,7 @@ public class RedisStringIdempotentRepositoryManualIT extends CamelTestSupport {
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
-        idempotentRepository = new RedisStringIdempotentRepository(
+        idempotentRepository = new SpringRedisStringIdempotentRepository(
                 redisTemplate,
                 "redis-idempotent-repository");
         RouteBuilder rb = new RouteBuilder() {
diff --git a/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepositoryTest.java b/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepositoryTest.java
index 0655242ce7a..d70467aa113 100644
--- a/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepositoryTest.java
+++ b/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisStringIdempotentRepositoryTest.java
@@ -50,15 +50,15 @@ public class RedisStringIdempotentRepositoryTest {
     @Mock
     private ValueOperations<String, String> valueOperations;
 
-    private RedisStringIdempotentRepository idempotentRepository;
-    private RedisStringIdempotentRepository idempotentRepositoryNoExpiry;
+    private SpringRedisStringIdempotentRepository idempotentRepository;
+    private SpringRedisStringIdempotentRepository idempotentRepositoryNoExpiry;
 
     @BeforeEach
     public void setUp() throws Exception {
         when(redisTemplate.opsForValue()).thenReturn(valueOperations);
-        idempotentRepository = new RedisStringIdempotentRepository(redisTemplate, REPOSITORY);
+        idempotentRepository = new SpringRedisStringIdempotentRepository(redisTemplate, REPOSITORY);
         idempotentRepository.setExpiry(1000L);
-        idempotentRepositoryNoExpiry = new RedisStringIdempotentRepository(redisTemplate, REPOSITORY_NOEXPIRY);
+        idempotentRepositoryNoExpiry = new SpringRedisStringIdempotentRepository(redisTemplate, REPOSITORY_NOEXPIRY);
     }
 
     @Test
@@ -79,9 +79,9 @@ public class RedisStringIdempotentRepositoryTest {
 
     @Test
     public void shouldReturnProcessorName() {
-        String processorName = idempotentRepository.getProcessorName();
+        String processorName = idempotentRepository.getRepositoryName();
         assertEquals(REPOSITORY, processorName);
-        String processorNameNoExpiry = idempotentRepositoryNoExpiry.getProcessorName();
+        String processorNameNoExpiry = idempotentRepositoryNoExpiry.getRepositoryName();
         assertEquals(REPOSITORY_NOEXPIRY, processorNameNoExpiry);
     }
 
diff --git a/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisIdempotentRepositoryTest.java b/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepositoryTest.java
similarity index 90%
rename from components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisIdempotentRepositoryTest.java
rename to components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepositoryTest.java
index 92a77ae93e1..f2fe5aa2f3e 100644
--- a/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/RedisIdempotentRepositoryTest.java
+++ b/components/camel-spring-redis/src/test/java/org/apache/camel/component/redis/processor/idempotent/SpringRedisIdempotentRepositoryTest.java
@@ -31,7 +31,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 @MockitoSettings(strictness = Strictness.LENIENT)
-public class RedisIdempotentRepositoryTest {
+public class SpringRedisIdempotentRepositoryTest {
 
     private static final String REPOSITORY = "testRepository";
     private static final String KEY = "KEY";
@@ -45,14 +45,14 @@ public class RedisIdempotentRepositoryTest {
     @Mock
     private SetOperations<String, String> setOperations;
 
-    private RedisIdempotentRepository idempotentRepository;
+    private SpringRedisIdempotentRepository idempotentRepository;
 
     @BeforeEach
     public void setUp() throws Exception {
         when(redisTemplate.opsForSet()).thenReturn(setOperations);
         when(redisTemplate.getConnectionFactory()).thenReturn(redisConnectionFactory);
         when(redisTemplate.getConnectionFactory().getConnection()).thenReturn(redisConnection);
-        idempotentRepository = RedisIdempotentRepository.redisIdempotentRepository(redisTemplate, REPOSITORY);
+        idempotentRepository = SpringRedisIdempotentRepository.redisIdempotentRepository(redisTemplate, REPOSITORY);
     }
 
     @Test
@@ -81,7 +81,7 @@ public class RedisIdempotentRepositoryTest {
 
     @Test
     public void shouldReturnProcessorName() {
-        String processorName = idempotentRepository.getProcessorName();
+        String processorName = idempotentRepository.getRepositoryName();
         assertEquals(REPOSITORY, processorName);
     }
 }
diff --git a/components/camel-spring-redis/src/test/resources/RedisComponentSpringTest-context.xml b/components/camel-spring-redis/src/test/resources/RedisComponentSpringTest-context.xml
index 16572ff49bd..68466db0064 100644
--- a/components/camel-spring-redis/src/test/resources/RedisComponentSpringTest-context.xml
+++ b/components/camel-spring-redis/src/test/resources/RedisComponentSpringTest-context.xml
@@ -23,7 +23,7 @@
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
 
-    <bean id="idempotentRepository" class="org.apache.camel.component.redis.processor.idempotent.RedisIdempotentRepository">
+    <bean id="idempotentRepository" class="org.apache.camel.component.redis.processor.idempotent.SpringRedisIdempotentRepository">
         <constructor-arg value="test-repo"/>
     </bean>
 
diff --git a/components/camel-sql/src/generated/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepositoryConfigurer.java b/components/camel-sql/src/generated/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..eb4b398aeda
--- /dev/null
+++ b/components/camel-sql/src/generated/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepositoryConfigurer.java
@@ -0,0 +1,136 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate.jdbc;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class JdbcAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository target = (org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": target.setAllowSerializedHeaders(property(camelContext, boolean.class, value)); return true;
+        case "datasource":
+        case "DataSource": target.setDataSource(property(camelContext, javax.sql.DataSource.class, value)); return true;
+        case "deadletteruri":
+        case "DeadLetterUri": target.setDeadLetterUri(property(camelContext, java.lang.String.class, value)); return true;
+        case "deserializationfilter":
+        case "DeserializationFilter": target.setDeserializationFilter(property(camelContext, java.lang.String.class, value)); return true;
+        case "headerstostoreastext":
+        case "HeadersToStoreAsText": target.setHeadersToStoreAsText(property(camelContext, java.util.List.class, value)); return true;
+        case "jdbcoptimisticlockingexceptionmapper":
+        case "JdbcOptimisticLockingExceptionMapper": target.setJdbcOptimisticLockingExceptionMapper(property(camelContext, org.apache.camel.processor.aggregate.jdbc.JdbcOptimisticLockingExceptionMapper.class, value)); return true;
+        case "lobhandler":
+        case "LobHandler": target.setLobHandler(property(camelContext, org.springframework.jdbc.support.lob.LobHandler.class, value)); return true;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": target.setMaximumRedeliveries(property(camelContext, int.class, value)); return true;
+        case "propagationbehaviorname":
+        case "PropagationBehaviorName": target.setPropagationBehaviorName(property(camelContext, java.lang.String.class, value)); return true;
+        case "recoveryinterval":
+        case "RecoveryInterval": target.setRecoveryInterval(property(camelContext, long.class, value)); return true;
+        case "repositoryname":
+        case "RepositoryName": target.setRepositoryName(property(camelContext, java.lang.String.class, value)); return true;
+        case "storebodyastext":
+        case "StoreBodyAsText": target.setStoreBodyAsText(property(camelContext, boolean.class, value)); return true;
+        case "transactionmanager":
+        case "TransactionManager": target.setTransactionManager(property(camelContext, org.springframework.transaction.PlatformTransactionManager.class, value)); return true;
+        case "userecovery":
+        case "UseRecovery": target.setUseRecovery(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return boolean.class;
+        case "datasource":
+        case "DataSource": return javax.sql.DataSource.class;
+        case "deadletteruri":
+        case "DeadLetterUri": return java.lang.String.class;
+        case "deserializationfilter":
+        case "DeserializationFilter": return java.lang.String.class;
+        case "headerstostoreastext":
+        case "HeadersToStoreAsText": return java.util.List.class;
+        case "jdbcoptimisticlockingexceptionmapper":
+        case "JdbcOptimisticLockingExceptionMapper": return org.apache.camel.processor.aggregate.jdbc.JdbcOptimisticLockingExceptionMapper.class;
+        case "lobhandler":
+        case "LobHandler": return org.springframework.jdbc.support.lob.LobHandler.class;
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return int.class;
+        case "propagationbehaviorname":
+        case "PropagationBehaviorName": return java.lang.String.class;
+        case "recoveryinterval":
+        case "RecoveryInterval": return long.class;
+        case "repositoryname":
+        case "RepositoryName": return java.lang.String.class;
+        case "storebodyastext":
+        case "StoreBodyAsText": return boolean.class;
+        case "transactionmanager":
+        case "TransactionManager": return org.springframework.transaction.PlatformTransactionManager.class;
+        case "userecovery":
+        case "UseRecovery": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository target = (org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowserializedheaders":
+        case "AllowSerializedHeaders": return target.isAllowSerializedHeaders();
+        case "datasource":
+        case "DataSource": return target.getDataSource();
+        case "deadletteruri":
+        case "DeadLetterUri": return target.getDeadLetterUri();
+        case "deserializationfilter":
+        case "DeserializationFilter": return target.getDeserializationFilter();
+        case "headerstostoreastext":
+        case "HeadersToStoreAsText": return target.getHeadersToStoreAsText();
+        case "jdbcoptimisticlockingexceptionmapper":
+        case "JdbcOptimisticLockingExceptionMapper": return target.getJdbcOptimisticLockingExceptionMapper();
+        case "lobhandler":
+        case "LobHandler": return target.getLobHandler();
+        case "maximumredeliveries":
+        case "MaximumRedeliveries": return target.getMaximumRedeliveries();
+        case "propagationbehaviorname":
+        case "PropagationBehaviorName": return target.getPropagationBehaviorName();
+        case "recoveryinterval":
+        case "RecoveryInterval": return target.getRecoveryInterval();
+        case "repositoryname":
+        case "RepositoryName": return target.getRepositoryName();
+        case "storebodyastext":
+        case "StoreBodyAsText": return target.isStoreBodyAsText();
+        case "transactionmanager":
+        case "TransactionManager": return target.getTransactionManager();
+        case "userecovery":
+        case "UseRecovery": return target.isUseRecovery();
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "headerstostoreastext":
+        case "HeadersToStoreAsText": return java.lang.String.class;
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-sql/src/generated/java/org/apache/camel/processor/idempotent/jdbc/JdbcMessageIdRepositoryConfigurer.java b/components/camel-sql/src/generated/java/org/apache/camel/processor/idempotent/jdbc/JdbcMessageIdRepositoryConfigurer.java
new file mode 100644
index 00000000000..b5ce0293f25
--- /dev/null
+++ b/components/camel-sql/src/generated/java/org/apache/camel/processor/idempotent/jdbc/JdbcMessageIdRepositoryConfigurer.java
@@ -0,0 +1,109 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.idempotent.jdbc;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class JdbcMessageIdRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository target = (org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "clearstring":
+        case "ClearString": target.setClearString(property(camelContext, java.lang.String.class, value)); return true;
+        case "createstring":
+        case "CreateString": target.setCreateString(property(camelContext, java.lang.String.class, value)); return true;
+        case "createtableifnotexists":
+        case "CreateTableIfNotExists": target.setCreateTableIfNotExists(property(camelContext, boolean.class, value)); return true;
+        case "deletestring":
+        case "DeleteString": target.setDeleteString(property(camelContext, java.lang.String.class, value)); return true;
+        case "insertstring":
+        case "InsertString": target.setInsertString(property(camelContext, java.lang.String.class, value)); return true;
+        case "jdbctemplate":
+        case "JdbcTemplate": target.setJdbcTemplate(property(camelContext, org.springframework.jdbc.core.JdbcTemplate.class, value)); return true;
+        case "processorname":
+        case "ProcessorName": target.setProcessorName(property(camelContext, java.lang.String.class, value)); return true;
+        case "querystring":
+        case "QueryString": target.setQueryString(property(camelContext, java.lang.String.class, value)); return true;
+        case "tableexistsstring":
+        case "TableExistsString": target.setTableExistsString(property(camelContext, java.lang.String.class, value)); return true;
+        case "tablename":
+        case "TableName": target.setTableName(property(camelContext, java.lang.String.class, value)); return true;
+        case "transactiontemplate":
+        case "TransactionTemplate": target.setTransactionTemplate(property(camelContext, org.springframework.transaction.support.TransactionTemplate.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "clearstring":
+        case "ClearString": return java.lang.String.class;
+        case "createstring":
+        case "CreateString": return java.lang.String.class;
+        case "createtableifnotexists":
+        case "CreateTableIfNotExists": return boolean.class;
+        case "deletestring":
+        case "DeleteString": return java.lang.String.class;
+        case "insertstring":
+        case "InsertString": return java.lang.String.class;
+        case "jdbctemplate":
+        case "JdbcTemplate": return org.springframework.jdbc.core.JdbcTemplate.class;
+        case "processorname":
+        case "ProcessorName": return java.lang.String.class;
+        case "querystring":
+        case "QueryString": return java.lang.String.class;
+        case "tableexistsstring":
+        case "TableExistsString": return java.lang.String.class;
+        case "tablename":
+        case "TableName": return java.lang.String.class;
+        case "transactiontemplate":
+        case "TransactionTemplate": return org.springframework.transaction.support.TransactionTemplate.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository target = (org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "clearstring":
+        case "ClearString": return target.getClearString();
+        case "createstring":
+        case "CreateString": return target.getCreateString();
+        case "createtableifnotexists":
+        case "CreateTableIfNotExists": return target.isCreateTableIfNotExists();
+        case "deletestring":
+        case "DeleteString": return target.getDeleteString();
+        case "insertstring":
+        case "InsertString": return target.getInsertString();
+        case "jdbctemplate":
+        case "JdbcTemplate": return target.getJdbcTemplate();
+        case "processorname":
+        case "ProcessorName": return target.getProcessorName();
+        case "querystring":
+        case "QueryString": return target.getQueryString();
+        case "tableexistsstring":
+        case "TableExistsString": return target.getTableExistsString();
+        case "tablename":
+        case "TableName": return target.getTableName();
+        case "transactiontemplate":
+        case "TransactionTemplate": return target.getTransactionTemplate();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..71dd5efccd9
--- /dev/null
+++ b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=JdbcAggregationRepository JdbcMessageIdRepository
+groupId=org.apache.camel
+artifactId=camel-sql
+version=4.5.0-SNAPSHOT
+projectName=Camel :: SQL
+projectDescription=Camel SQL support
diff --git a/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcAggregationRepository.json b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcAggregationRepository.json
new file mode 100644
index 00000000000..44957e05cba
--- /dev/null
+++ b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "JdbcAggregationRepository",
+    "javaType": "org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository",
+    "interfaceType": "org.apache.camel.spi.AggregationRepository",
+    "title": "Jdbc Aggregation Repository",
+    "description": "Aggregation repository that uses SQL database to store exchanges.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-sql",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "dataSource": { "index": 0, "kind": "property", "displayName": "Data Source", "required": true, "type": "object", "javaType": "org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "The DataSource to use for connecting to the database" }, "transactionManager": { "index": 1, "kind": "property", "displayName": "Transaction Manager", "required": true, "type": "object", "javaType": "o [...]
+  }
+}
+
diff --git a/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcMessageIdRepository.json b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcMessageIdRepository.json
new file mode 100644
index 00000000000..0c49743805b
--- /dev/null
+++ b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/bean/JdbcMessageIdRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "JdbcMessageIdRepository",
+    "javaType": "org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Jdbc Message Id Repository",
+    "description": "Idempotent repository that uses a SQL database to store message ids.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-sql",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "tableName": { "index": 0, "kind": "property", "displayName": "Table Name", "required": false, "type": "object", "javaType": "org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "CAMEL_MESSAGEPROCESSED", "description": "The name of the table to use in the database" }, "createTableIfNotExists": { "index": 1, "kind": "property", "displayName": "Create Table If Not Exists", "requir [...]
+  }
+}
+
diff --git a/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository
new file mode 100644
index 00000000000..c37a4ee368b
--- /dev/null
+++ b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepositoryConfigurer
diff --git a/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository
new file mode 100644
index 00000000000..7d7d29d170c
--- /dev/null
+++ b/components/camel-sql/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepositoryConfigurer
diff --git a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/ClusteredJdbcAggregationRepository.java b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/ClusteredJdbcAggregationRepository.java
index 0c87afc0de3..04f3d7a9571 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/ClusteredJdbcAggregationRepository.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/ClusteredJdbcAggregationRepository.java
@@ -136,7 +136,7 @@ public class ClusteredJdbcAggregationRepository extends JdbcAggregationRepositor
             final CamelContext camelContext, final String key, final Exchange exchange,
             final String sql, final Long version, final boolean completed)
             throws Exception {
-        final byte[] data = codec.marshallExchange(exchange, allowSerializedHeaders);
+        final byte[] data = jdbcCamelCodec.marshallExchange(exchange, isAllowSerializedHeaders());
         Integer insertCount = super.jdbcTemplate.execute(sql,
                 new AbstractLobCreatingPreparedStatementCallback(getLobHandler()) {
                     @Override
diff --git a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/ClusteredPostgresAggregationRepository.java b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/ClusteredPostgresAggregationRepository.java
index fdb0b75215a..dd46bce0e62 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/ClusteredPostgresAggregationRepository.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/ClusteredPostgresAggregationRepository.java
@@ -25,7 +25,7 @@ import org.springframework.transaction.PlatformTransactionManager;
 
 /**
  * PostgreSQL specific {@link JdbcAggregationRepository} that deals with SQL Violation Exceptions using special
- * {@code INSERT INTO .. ON CONFLICT DO NOTHING} claues.
+ * {@code INSERT INTO .. ON CONFLICT DO NOTHING} clause.
  */
 public class ClusteredPostgresAggregationRepository extends ClusteredJdbcAggregationRepository {
 
diff --git a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepository.java b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepository.java
index e016df45376..3c6d2725c9f 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepository.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregationRepository.java
@@ -33,6 +33,8 @@ import javax.sql.DataSource;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.OptimisticLockingAggregationRepository;
 import org.apache.camel.spi.RecoverableAggregationRepository;
 import org.apache.camel.support.service.ServiceSupport;
@@ -60,6 +62,10 @@ import org.springframework.transaction.support.TransactionTemplate;
  * Serializable compatible data types. If a data type is not such a type its dropped and a WARN is logged. And it only
  * persists the Message body and the Message headers. The Exchange properties are not persisted.
  */
+@Metadata(label = "bean",
+          description = "Aggregation repository that uses SQL database to store exchanges.",
+          annotations = { "interfaceName=org.apache.camel.spi.AggregationRepository" })
+@Configurer(metadataOnly = true)
 public class JdbcAggregationRepository extends ServiceSupport
         implements RecoverableAggregationRepository, OptimisticLockingAggregationRepository {
 
@@ -74,27 +80,48 @@ public class JdbcAggregationRepository extends ServiceSupport
     private static final Logger LOG = LoggerFactory.getLogger(JdbcAggregationRepository.class);
     private static final Constants PROPAGATION_CONSTANTS = new Constants(TransactionDefinition.class);
 
-    protected JdbcCamelCodec codec = new JdbcCamelCodec();
-    protected JdbcTemplate jdbcTemplate;
+    protected JdbcCamelCodec jdbcCamelCodec = new JdbcCamelCodec();
     protected TransactionTemplate transactionTemplate;
     protected TransactionTemplate transactionTemplateReadOnly;
-    protected boolean allowSerializedHeaders;
+    protected JdbcTemplate jdbcTemplate;
+    private boolean returnOldExchange;
+    private int propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRED;
 
-    private JdbcOptimisticLockingExceptionMapper jdbcOptimisticLockingExceptionMapper
-            = new DefaultJdbcOptimisticLockingExceptionMapper();
-    private PlatformTransactionManager transactionManager;
+    @Metadata(description = "The DataSource to use for connecting to the database", required = true)
     private DataSource dataSource;
-    private int propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRED;
-    private LobHandler lobHandler = new DefaultLobHandler();
+    @Metadata(description = "The Spring TransactionManager to use for connecting to the database", required = true)
+    private PlatformTransactionManager transactionManager;
+    @Metadata(description = "The name of the repository.")
     private String repositoryName;
-    private boolean returnOldExchange;
-    private long recoveryInterval = 5000;
+    @Metadata(javaType = "java.lang.String",
+              description = "Allows to store headers as String which is human readable. By default this option is disabled, storing the headers in binary format."
+                            + " Multiple header names can be separated by comma.")
+    private List<String> headersToStoreAsText;
+    @Metadata(description = "Whether to store the message body as String which is human readable. By default this option is false storing the body in binary format.")
+    private boolean storeBodyAsText;
+    @Metadata(description = "Whether or not recovery is enabled", defaultValue = "true")
     private boolean useRecovery = true;
+    @Metadata(description = "Sets the interval between recovery scans", defaultValue = "5000")
+    private long recoveryInterval = 5000;
+    @Metadata(description = "Sets an optional limit of the number of redelivery attempt of recovered Exchange should be attempted, before its exhausted."
+                            + " When this limit is hit, then the Exchange is moved to the dead letter channel.")
     private int maximumRedeliveries;
+    @Metadata(description = "Sets an optional dead letter channel which exhausted recovered Exchange should be send to.")
     private String deadLetterUri;
-    private List<String> headersToStoreAsText;
-    private boolean storeBodyAsText;
+    @Metadata(label = "advanced",
+              description = "Whether headers on the Exchange that are Java objects and Serializable should be included and saved to the repository")
+    private boolean allowSerializedHeaders;
+    @Metadata(label = "security", defaultValue = "java.**;org.apache.camel.**;!*",
+              description = "Sets a deserialization filter while reading Object from Aggregation Repository. By default the filter will allow"
+                            + " all java packages and subpackages and all org.apache.camel packages and subpackages, while the remaining will be"
+                            + " blacklisted and not deserialized. This parameter should be customized if you're using classes you trust to be deserialized.")
     private String deserializationFilter = "java.**;org.apache.camel.**;!*";
+    @Metadata(label = "advanced",
+              description = "Mapper allowing different JDBC vendors to be mapped with vendor specific error codes to an OptimisticLockingException")
+    private JdbcOptimisticLockingExceptionMapper jdbcOptimisticLockingExceptionMapper
+            = new DefaultJdbcOptimisticLockingExceptionMapper();
+    @Metadata(label = "advanced", description = "To use a custom LobHandler")
+    private LobHandler lobHandler = new DefaultLobHandler();
 
     /**
      * Creates an aggregation repository
@@ -119,17 +146,24 @@ public class JdbcAggregationRepository extends ServiceSupport
         this.repositoryName = repositoryName;
     }
 
+    public PlatformTransactionManager getTransactionManager() {
+        return transactionManager;
+    }
+
     public final void setTransactionManager(PlatformTransactionManager transactionManager) {
         this.transactionManager = transactionManager;
     }
 
+    public DataSource getDataSource() {
+        return dataSource;
+    }
+
     /**
      * Sets the DataSource to use for accessing the database
      */
     public void setDataSource(DataSource dataSource) {
         this.dataSource = dataSource;
-
-        jdbcTemplate = new JdbcTemplate(dataSource);
+        this.jdbcTemplate = new JdbcTemplate(dataSource);
     }
 
     @Override
@@ -276,7 +310,7 @@ public class JdbcAggregationRepository extends ServiceSupport
     protected int insertHelper(
             final CamelContext camelContext, final String key, final Exchange exchange, String sql, final Long version)
             throws Exception {
-        final byte[] data = codec.marshallExchange(exchange, allowSerializedHeaders);
+        final byte[] data = jdbcCamelCodec.marshallExchange(exchange, allowSerializedHeaders);
         Integer insertCount = jdbcTemplate.execute(sql,
                 new AbstractLobCreatingPreparedStatementCallback(getLobHandler()) {
                     @Override
@@ -302,7 +336,7 @@ public class JdbcAggregationRepository extends ServiceSupport
     protected int updateHelper(
             final CamelContext camelContext, final String key, final Exchange exchange, String sql, final Long version)
             throws Exception {
-        final byte[] data = codec.marshallExchange(exchange, allowSerializedHeaders);
+        final byte[] data = jdbcCamelCodec.marshallExchange(exchange, allowSerializedHeaders);
         Integer updateCount = jdbcTemplate.execute(sql,
                 new AbstractLobCreatingPreparedStatementCallback(getLobHandler()) {
                     @Override
@@ -356,7 +390,8 @@ public class JdbcAggregationRepository extends ServiceSupport
                         version = (long) versionObj;
                     }
 
-                    Exchange result = codec.unmarshallExchange(camelContext, marshalledExchange, deserializationFilter);
+                    Exchange result
+                            = jdbcCamelCodec.unmarshallExchange(camelContext, marshalledExchange, deserializationFilter);
                     result.setProperty(VERSION_PROPERTY, version);
                     return result;
 
@@ -466,13 +501,13 @@ public class JdbcAggregationRepository extends ServiceSupport
     }
 
     @Override
-    public void setRecoveryInterval(long interval) {
-        this.recoveryInterval = interval;
+    public long getRecoveryInterval() {
+        return recoveryInterval;
     }
 
     @Override
-    public long getRecoveryIntervalInMillis() {
-        return recoveryInterval;
+    public void setRecoveryInterval(long interval) {
+        this.recoveryInterval = interval;
     }
 
     @Override
@@ -526,8 +561,12 @@ public class JdbcAggregationRepository extends ServiceSupport
         this.returnOldExchange = returnOldExchange;
     }
 
+    public JdbcCamelCodec getJdbcCamelCodec() {
+        return jdbcCamelCodec;
+    }
+
     public void setJdbcCamelCodec(JdbcCamelCodec codec) {
-        this.codec = codec;
+        this.jdbcCamelCodec = codec;
     }
 
     public boolean hasHeadersToStoreAsText() {
@@ -548,6 +587,10 @@ public class JdbcAggregationRepository extends ServiceSupport
         this.headersToStoreAsText = headersToStoreAsText;
     }
 
+    public void setHeadersToStoreAsText(String headers) {
+        this.headersToStoreAsText = List.of(headers.split(","));
+    }
+
     public boolean isStoreBodyAsText() {
         return storeBodyAsText;
     }
@@ -580,12 +623,14 @@ public class JdbcAggregationRepository extends ServiceSupport
         this.propagationBehavior = propagationBehavior;
     }
 
+    public String getPropagationBehaviorName() {
+        return PROPAGATION_CONSTANTS.asString("" + propagationBehavior);
+    }
+
     /**
      * Sets propagation behavior to use with spring transaction templates which are used for database access. The
      * default is TransactionDefinition.PROPAGATION_REQUIRED. This setter accepts names of the constants, like
      * "PROPAGATION_REQUIRED".
-     *
-     * @param propagationBehaviorName
      */
     public void setPropagationBehaviorName(String propagationBehaviorName) {
         if (!propagationBehaviorName.startsWith(DefaultTransactionDefinition.PREFIX_PROPAGATION)) {
diff --git a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/PostgresAggregationRepository.java b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/PostgresAggregationRepository.java
index 585011782f2..e906f6fc75c 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/PostgresAggregationRepository.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/processor/aggregate/jdbc/PostgresAggregationRepository.java
@@ -25,7 +25,7 @@ import org.springframework.transaction.PlatformTransactionManager;
 
 /**
  * PostgreSQL specific {@link JdbcAggregationRepository} that deals with SQL Violation Exceptions using special
- * {@code INSERT INTO .. ON CONFLICT DO NOTHING} claues.
+ * {@code INSERT INTO .. ON CONFLICT DO NOTHING} clause.
  */
 public class PostgresAggregationRepository extends JdbcAggregationRepository {
 
diff --git a/components/camel-sql/src/main/java/org/apache/camel/processor/idempotent/jdbc/AbstractJdbcMessageIdRepository.java b/components/camel-sql/src/main/java/org/apache/camel/processor/idempotent/jdbc/AbstractJdbcMessageIdRepository.java
index b68b2ef4e33..17eadaadaaf 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/processor/idempotent/jdbc/AbstractJdbcMessageIdRepository.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/processor/idempotent/jdbc/AbstractJdbcMessageIdRepository.java
@@ -21,6 +21,7 @@ import javax.sql.DataSource;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.service.ServiceSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,11 +52,16 @@ import org.springframework.transaction.support.TransactionTemplate;
 @ManagedResource(description = "JDBC IdempotentRepository")
 public abstract class AbstractJdbcMessageIdRepository extends ServiceSupport implements IdempotentRepository {
 
-    protected JdbcTemplate jdbcTemplate;
+    protected Logger log = LoggerFactory.getLogger(getClass());
+
+    @Metadata(description = "The name of the processor that are used for this repository. Use unique names to separate processors in the same database.",
+              required = true)
     protected String processorName;
+    @Metadata(description = "The Spring JdbcTemplate to use for connecting to the database", required = true)
+    protected JdbcTemplate jdbcTemplate;
+    @Metadata(description = "The Spring TransactionTemplate to use for connecting to the database", required = true)
     protected TransactionTemplate transactionTemplate;
-    protected DataSource dataSource;
-    protected Logger log = LoggerFactory.getLogger(getClass());
+    protected DataSource dataSource; // not in use
 
     public AbstractJdbcMessageIdRepository() {
     }
diff --git a/components/camel-sql/src/main/java/org/apache/camel/processor/idempotent/jdbc/JdbcMessageIdRepository.java b/components/camel-sql/src/main/java/org/apache/camel/processor/idempotent/jdbc/JdbcMessageIdRepository.java
index af70a6c5a1e..de90efbda9e 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/processor/idempotent/jdbc/JdbcMessageIdRepository.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/processor/idempotent/jdbc/JdbcMessageIdRepository.java
@@ -20,6 +20,8 @@ import java.sql.Timestamp;
 
 import javax.sql.DataSource;
 
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.transaction.TransactionStatus;
@@ -29,6 +31,10 @@ import org.springframework.transaction.support.TransactionTemplate;
 /**
  * Default implementation of {@link AbstractJdbcMessageIdRepository}
  */
+@Metadata(label = "bean",
+          description = "Idempotent repository that uses a SQL database to store message ids.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 public class JdbcMessageIdRepository extends AbstractJdbcMessageIdRepository {
 
     protected static final String DEFAULT_TABLENAME = "CAMEL_MESSAGEPROCESSED";
@@ -44,14 +50,22 @@ public class JdbcMessageIdRepository extends AbstractJdbcMessageIdRepository {
             = "DELETE FROM CAMEL_MESSAGEPROCESSED WHERE processorName = ? AND messageId = ?";
     protected static final String DEFAULT_CLEAR_STRING = "DELETE FROM CAMEL_MESSAGEPROCESSED WHERE processorName = ?";
 
-    private boolean createTableIfNotExists = true;
+    @Metadata(description = "The name of the table to use in the database", defaultValue = "CAMEL_MESSAGEPROCESSED")
     private String tableName;
+    @Metadata(description = "Whether to create the table in the database if none exists on startup", defaultValue = "true")
+    private boolean createTableIfNotExists = true;
 
+    @Metadata(label = "advanced", description = "SQL query to use for checking if table exists")
     private String tableExistsString = DEFAULT_TABLE_EXISTS_STRING;
+    @Metadata(label = "advanced", description = "SQL query to use for creating table")
     private String createString = DEFAULT_CREATE_STRING;
+    @Metadata(label = "advanced", description = "SQL query to use for check if message id already exists")
     private String queryString = DEFAULT_QUERY_STRING;
+    @Metadata(label = "advanced", description = "SQL query to use for inserting a new message id in the table")
     private String insertString = DEFAULT_INSERT_STRING;
+    @Metadata(label = "advanced", description = "SQL query to use for deleting message id from the table")
     private String deleteString = DEFAULT_DELETE_STRING;
+    @Metadata(label = "advanced", description = "SQL query to delete all message ids from the table")
     private String clearString = DEFAULT_CLEAR_STRING;
 
     public JdbcMessageIdRepository() {
diff --git a/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregateStoreAsTextTest.java b/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregateStoreAsTextTest.java
index 3d12b9571c1..d2e6c71d638 100644
--- a/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregateStoreAsTextTest.java
+++ b/components/camel-sql/src/test/java/org/apache/camel/processor/aggregate/jdbc/JdbcAggregateStoreAsTextTest.java
@@ -18,6 +18,7 @@ package org.apache.camel.processor.aggregate.jdbc;
 
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.sql.DataSource;
@@ -103,7 +104,7 @@ public class JdbcAggregateStoreAsTextTest extends CamelSpringTestSupport {
         mock.expectedBodiesReceived("ABCDE");
 
         repo.setStoreBodyAsText(true);
-        repo.setHeadersToStoreAsText(null);
+        repo.setHeadersToStoreAsText((List) null);
 
         Map<String, Object> headers = new HashMap<>();
         headers.put("id", 123);
diff --git a/components/camel-tarfile/src/generated/java/org/apache/camel/processor/aggregate/tarfile/TarAggregationStrategyConfigurer.java b/components/camel-tarfile/src/generated/java/org/apache/camel/processor/aggregate/tarfile/TarAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..3a3a6f0be5d
--- /dev/null
+++ b/components/camel-tarfile/src/generated/java/org/apache/camel/processor/aggregate/tarfile/TarAggregationStrategyConfigurer.java
@@ -0,0 +1,61 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate.tarfile;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class TarAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy target = (org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "fileprefix":
+        case "FilePrefix": target.setFilePrefix(property(camelContext, java.lang.String.class, value)); return true;
+        case "filesuffix":
+        case "FileSuffix": target.setFileSuffix(property(camelContext, java.lang.String.class, value)); return true;
+        case "parentdir":
+        case "ParentDir": target.setParentDir(property(camelContext, java.io.File.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "fileprefix":
+        case "FilePrefix": return java.lang.String.class;
+        case "filesuffix":
+        case "FileSuffix": return java.lang.String.class;
+        case "parentdir":
+        case "ParentDir": return java.io.File.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy target = (org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "fileprefix":
+        case "FilePrefix": return target.getFilePrefix();
+        case "filesuffix":
+        case "FileSuffix": return target.getFileSuffix();
+        case "parentdir":
+        case "ParentDir": return target.getParentDir();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..ca831f80dbb
--- /dev/null
+++ b/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=TarAggregationStrategy
+groupId=org.apache.camel
+artifactId=camel-tarfile
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Tar File
+projectDescription=Camel Tar file support
diff --git a/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/bean/TarAggregationStrategy.json b/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/bean/TarAggregationStrategy.json
new file mode 100644
index 00000000000..f089769724c
--- /dev/null
+++ b/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/bean/TarAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "TarAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Tar Aggregation Strategy",
+    "description": "AggregationStrategy to combine together incoming messages into a tar file. Please note that this aggregation strategy requires eager completion check to work properly.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-tarfile",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "filePrefix": { "index": 0, "kind": "property", "displayName": "File Prefix", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the prefix that will be used when creating the TAR filename." }, "fileSuffix": { "index": 1, "kind": "property", "displayName": "File Suffix", "required": false, "type": "object", "javaType": "or [...]
+  }
+}
+
diff --git a/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy b/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy
new file mode 100644
index 00000000000..6b9545ef2ba
--- /dev/null
+++ b/components/camel-tarfile/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.tarfile.TarAggregationStrategyConfigurer
diff --git a/components/camel-tarfile/src/main/java/org/apache/camel/processor/aggregate/tarfile/TarAggregationStrategy.java b/components/camel-tarfile/src/main/java/org/apache/camel/processor/aggregate/tarfile/TarAggregationStrategy.java
index 512f7911966..2b671b04b69 100644
--- a/components/camel-tarfile/src/main/java/org/apache/camel/processor/aggregate/tarfile/TarAggregationStrategy.java
+++ b/components/camel-tarfile/src/main/java/org/apache/camel/processor/aggregate/tarfile/TarAggregationStrategy.java
@@ -31,6 +31,8 @@ import org.apache.camel.component.file.FileConsumer;
 import org.apache.camel.component.file.GenericFile;
 import org.apache.camel.component.file.GenericFileMessage;
 import org.apache.camel.component.file.GenericFileOperationFailedException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.Synchronization;
 import org.apache.camel.util.FileUtil;
 import org.apache.commons.compress.archivers.ArchiveException;
@@ -59,14 +61,26 @@ import org.slf4j.LoggerFactory;
  * tar file.
  * </p>
  */
+@Metadata(label = "bean",
+          description = "AggregationStrategy to combine together incoming messages into a tar file."
+                        + " Please note that this aggregation strategy requires eager completion check to work properly.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class TarAggregationStrategy implements AggregationStrategy {
 
     private static final Logger LOG = LoggerFactory.getLogger(TarAggregationStrategy.class);
 
+    @Metadata(description = "Sets the prefix that will be used when creating the TAR filename.")
     private String filePrefix;
+    @Metadata(description = "Sets the suffix that will be used when creating the TAR filename.", defaultValue = "tar")
     private String fileSuffix = ".tar";
+    @Metadata(label = "advanced",
+              description = "If the incoming message is from a file, then the folder structure of said file can be preserved")
     private boolean preserveFolderStructure;
+    @Metadata(label = "advanced",
+              description = "Whether to use CamelFileName header for the filename instead of using unique message id")
     private boolean useFilenameHeader;
+    @Metadata(label = "advanced", description = "Sets the parent directory to use for writing temporary files")
     private File parentDir = new File(System.getProperty("java.io.tmpdir"));
 
     public TarAggregationStrategy() {
diff --git a/components/camel-xslt-saxon/src/generated/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategyConfigurer.java b/components/camel-xslt-saxon/src/generated/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..630598e4199
--- /dev/null
+++ b/components/camel-xslt-saxon/src/generated/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategyConfigurer.java
@@ -0,0 +1,67 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.xslt.saxon;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class XsltSaxonAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy target = (org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "output":
+        case "Output": target.setOutput(property(camelContext, org.apache.camel.component.xslt.XsltOutput.class, value)); return true;
+        case "propertyname":
+        case "PropertyName": target.setPropertyName(property(camelContext, java.lang.String.class, value)); return true;
+        case "transformerfactoryclass":
+        case "TransformerFactoryClass": target.setTransformerFactoryClass(property(camelContext, java.lang.String.class, value)); return true;
+        case "xslfile":
+        case "XslFile": target.setXslFile(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "output":
+        case "Output": return org.apache.camel.component.xslt.XsltOutput.class;
+        case "propertyname":
+        case "PropertyName": return java.lang.String.class;
+        case "transformerfactoryclass":
+        case "TransformerFactoryClass": return java.lang.String.class;
+        case "xslfile":
+        case "XslFile": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy target = (org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "output":
+        case "Output": return target.getOutput();
+        case "propertyname":
+        case "PropertyName": return target.getPropertyName();
+        case "transformerfactoryclass":
+        case "TransformerFactoryClass": return target.getTransformerFactoryClass();
+        case "xslfile":
+        case "XslFile": return target.getXslFile();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..1052be3f7b9
--- /dev/null
+++ b/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=XsltSaxonAggregationStrategy
+groupId=org.apache.camel
+artifactId=camel-xslt-saxon
+version=4.5.0-SNAPSHOT
+projectName=Camel :: XSLT Saxon
+projectDescription=Camel XSLT Saxon component
diff --git a/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/bean/XsltSaxonAggregationStrategy.json b/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/bean/XsltSaxonAggregationStrategy.json
new file mode 100644
index 00000000000..81e5ceb406c
--- /dev/null
+++ b/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/bean/XsltSaxonAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "XsltSaxonAggregationStrategy",
+    "javaType": "org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Xslt Saxon Aggregation Strategy",
+    "description": "The XSLT Aggregation Strategy enables you to use XSL stylesheets to aggregate messages (uses Saxon).",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-xslt-saxon",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "xslFile": { "index": 0, "kind": "property", "displayName": "Xsl File", "required": true, "type": "object", "javaType": "org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the XSL transformation file to use" }, "propertyName": { "index": 1, "kind": "property", "displayName": "Property Name", "required": false, "type": "object", "javaType": "org.apache.camel.componen [...]
+  }
+}
+
diff --git a/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy b/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy
new file mode 100644
index 00000000000..be8712de70a
--- /dev/null
+++ b/components/camel-xslt-saxon/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.xslt.saxon.XsltSaxonAggregationStrategyConfigurer
diff --git a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategy.java b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategy.java
index 6ceccea2a28..cf86c3d4b01 100644
--- a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategy.java
+++ b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategy.java
@@ -16,12 +16,38 @@
  */
 package org.apache.camel.component.xslt.saxon;
 
+import javax.xml.transform.TransformerFactory;
+
 import net.sf.saxon.TransformerFactoryImpl;
 import org.apache.camel.component.xslt.XsltAggregationStrategy;
 import org.apache.camel.component.xslt.XsltBuilder;
+import org.apache.camel.component.xslt.XsltOutput;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 
+@Metadata(label = "bean",
+          description = "The XSLT Aggregation Strategy enables you to use XSL stylesheets to aggregate messages (uses Saxon).",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class XsltSaxonAggregationStrategy extends XsltAggregationStrategy {
 
+    // need to duplicate fields for code generation purpose
+
+    @Metadata(description = "The name of the XSL transformation file to use", required = true)
+    private String xslFile;
+    @Metadata(description = "The exchange property name that contains the XML payloads as an input",
+              defaultValue = "new-exchange")
+    private String propertyName;
+    @Metadata(defaultValue = "string", enums = "string,bytes,DOM,file",
+              description = "Option to specify which output type to use. Possible values are: string, bytes, DOM, file. The first three"
+                            + " options are all in memory based, where as file is streamed directly to a java.io.File. For file you must specify"
+                            + " the filename in the IN header with the key XsltConstants.XSLT_FILE_NAME which is also CamelXsltFileName. Also any"
+                            + " paths leading to the filename must be created beforehand, otherwise an exception is thrown at runtime.")
+    private XsltOutput output = XsltOutput.string;
+    @Metadata(label = "advanced", description = "To use a custom XSLT transformer factory, specified as a FQN class name")
+    private String transformerFactoryClass;
+    private TransformerFactory transformerFactory;
+
     public XsltSaxonAggregationStrategy(String xslFileLocation) {
         super(xslFileLocation);
         setTransformerFactory(new TransformerFactoryImpl());
diff --git a/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltAggregationStrategyConfigurer.java b/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..6d7bece6054
--- /dev/null
+++ b/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltAggregationStrategyConfigurer.java
@@ -0,0 +1,67 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.xslt;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.component.xslt.XsltAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class XsltAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.component.xslt.XsltAggregationStrategy target = (org.apache.camel.component.xslt.XsltAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "output":
+        case "Output": target.setOutput(property(camelContext, org.apache.camel.component.xslt.XsltOutput.class, value)); return true;
+        case "propertyname":
+        case "PropertyName": target.setPropertyName(property(camelContext, java.lang.String.class, value)); return true;
+        case "transformerfactoryclass":
+        case "TransformerFactoryClass": target.setTransformerFactoryClass(property(camelContext, java.lang.String.class, value)); return true;
+        case "xslfile":
+        case "XslFile": target.setXslFile(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "output":
+        case "Output": return org.apache.camel.component.xslt.XsltOutput.class;
+        case "propertyname":
+        case "PropertyName": return java.lang.String.class;
+        case "transformerfactoryclass":
+        case "TransformerFactoryClass": return java.lang.String.class;
+        case "xslfile":
+        case "XslFile": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.component.xslt.XsltAggregationStrategy target = (org.apache.camel.component.xslt.XsltAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "output":
+        case "Output": return target.getOutput();
+        case "propertyname":
+        case "PropertyName": return target.getPropertyName();
+        case "transformerfactoryclass":
+        case "TransformerFactoryClass": return target.getTransformerFactoryClass();
+        case "xslfile":
+        case "XslFile": return target.getXslFile();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..80d1359893b
--- /dev/null
+++ b/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=XsltAggregationStrategy
+groupId=org.apache.camel
+artifactId=camel-xslt
+version=4.5.0-SNAPSHOT
+projectName=Camel :: XSLT
+projectDescription=Camel XSLT component
diff --git a/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/bean/XsltAggregationStrategy.json b/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/bean/XsltAggregationStrategy.json
new file mode 100644
index 00000000000..8728d9f2a37
--- /dev/null
+++ b/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/bean/XsltAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "XsltAggregationStrategy",
+    "javaType": "org.apache.camel.component.xslt.XsltAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Xslt Aggregation Strategy",
+    "description": "The XSLT Aggregation Strategy enables you to use XSL stylesheets to aggregate messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-xslt",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "xslFile": { "index": 0, "kind": "property", "displayName": "Xsl File", "required": true, "type": "object", "javaType": "org.apache.camel.component.xslt.XsltAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "The name of the XSL transformation file to use" }, "propertyName": { "index": 1, "kind": "property", "displayName": "Property Name", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.Xslt [...]
+  }
+}
+
diff --git a/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.xslt.XsltAggregationStrategy b/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.xslt.XsltAggregationStrategy
new file mode 100644
index 00000000000..8bc4b41575e
--- /dev/null
+++ b/components/camel-xslt/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.component.xslt.XsltAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.xslt.XsltAggregationStrategyConfigurer
diff --git a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltAggregationStrategy.java b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltAggregationStrategy.java
index b22ac54b724..d6e89b8c497 100644
--- a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltAggregationStrategy.java
+++ b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltAggregationStrategy.java
@@ -30,6 +30,8 @@ import org.apache.camel.AggregationStrategy;
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.ResourceHelper;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
@@ -60,6 +62,10 @@ import org.slf4j.LoggerFactory;
  * <p>
  * Some code bits have been copied from the {@link org.apache.camel.component.xslt.XsltEndpoint}.
  */
+@Metadata(label = "bean",
+          description = "The XSLT Aggregation Strategy enables you to use XSL stylesheets to aggregate messages.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class XsltAggregationStrategy extends ServiceSupport implements AggregationStrategy, CamelContextAware {
 
     private static final Logger LOG = LoggerFactory.getLogger(XsltAggregationStrategy.class);
@@ -69,10 +75,19 @@ public class XsltAggregationStrategy extends ServiceSupport implements Aggregati
     private volatile URIResolver uriResolver;
     private CamelContext camelContext;
 
+    @Metadata(description = "The name of the XSL transformation file to use", required = true)
+    private String xslFile;
+    @Metadata(description = "The exchange property name that contains the XML payloads as an input",
+              defaultValue = "" + DEFAULT_PROPERTY_NAME)
     private String propertyName;
-    private final String xslFile;
     private TransformerFactory transformerFactory;
+    @Metadata(label = "advanced", description = "To use a custom XSLT transformer factory, specified as a FQN class name")
     private String transformerFactoryClass;
+    @Metadata(defaultValue = "string", enums = "string,bytes,DOM,file",
+              description = "Option to specify which output type to use. Possible values are: string, bytes, DOM, file. The first three"
+                            + " options are all in memory based, where as file is streamed directly to a java.io.File. For file you must specify"
+                            + " the filename in the IN header with the key XsltConstants.XSLT_FILE_NAME which is also CamelXsltFileName. Also any"
+                            + " paths leading to the filename must be created beforehand, otherwise an exception is thrown at runtime.")
     private XsltOutput output = XsltOutput.string;
 
     /**
@@ -84,6 +99,14 @@ public class XsltAggregationStrategy extends ServiceSupport implements Aggregati
         this.xslFile = xslFileLocation;
     }
 
+    public String getXslFile() {
+        return xslFile;
+    }
+
+    public void setXslFile(String xslFile) {
+        this.xslFile = xslFile;
+    }
+
     @Override
     public CamelContext getCamelContext() {
         return camelContext;
@@ -122,6 +145,10 @@ public class XsltAggregationStrategy extends ServiceSupport implements Aggregati
         return oldExchange;
     }
 
+    public XsltOutput getOutput() {
+        return output;
+    }
+
     public void setOutput(XsltOutput output) {
         this.output = output;
     }
@@ -134,6 +161,10 @@ public class XsltAggregationStrategy extends ServiceSupport implements Aggregati
         this.uriResolver = uriResolver;
     }
 
+    public String getTransformerFactoryClass() {
+        return transformerFactoryClass;
+    }
+
     public void setTransformerFactoryClass(String transformerFactoryClass) {
         this.transformerFactoryClass = transformerFactoryClass;
     }
diff --git a/components/camel-zipfile/src/generated/java/org/apache/camel/processor/aggregate/zipfile/ZipAggregationStrategyConfigurer.java b/components/camel-zipfile/src/generated/java/org/apache/camel/processor/aggregate/zipfile/ZipAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..da107a156e9
--- /dev/null
+++ b/components/camel-zipfile/src/generated/java/org/apache/camel/processor/aggregate/zipfile/ZipAggregationStrategyConfigurer.java
@@ -0,0 +1,79 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate.zipfile;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class ZipAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy target = (org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "fileprefix":
+        case "FilePrefix": target.setFilePrefix(property(camelContext, java.lang.String.class, value)); return true;
+        case "filesuffix":
+        case "FileSuffix": target.setFileSuffix(property(camelContext, java.lang.String.class, value)); return true;
+        case "parentdir":
+        case "ParentDir": target.setParentDir(property(camelContext, java.io.File.class, value)); return true;
+        case "preservefolderstructure":
+        case "PreserveFolderStructure": target.setPreserveFolderStructure(property(camelContext, boolean.class, value)); return true;
+        case "usefilenameheader":
+        case "UseFilenameHeader": target.setUseFilenameHeader(property(camelContext, boolean.class, value)); return true;
+        case "usetempfile":
+        case "UseTempFile": target.setUseTempFile(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "fileprefix":
+        case "FilePrefix": return java.lang.String.class;
+        case "filesuffix":
+        case "FileSuffix": return java.lang.String.class;
+        case "parentdir":
+        case "ParentDir": return java.io.File.class;
+        case "preservefolderstructure":
+        case "PreserveFolderStructure": return boolean.class;
+        case "usefilenameheader":
+        case "UseFilenameHeader": return boolean.class;
+        case "usetempfile":
+        case "UseTempFile": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy target = (org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "fileprefix":
+        case "FilePrefix": return target.getFilePrefix();
+        case "filesuffix":
+        case "FileSuffix": return target.getFileSuffix();
+        case "parentdir":
+        case "ParentDir": return target.getParentDir();
+        case "preservefolderstructure":
+        case "PreserveFolderStructure": return target.isPreserveFolderStructure();
+        case "usefilenameheader":
+        case "UseFilenameHeader": return target.isUseFilenameHeader();
+        case "usetempfile":
+        case "UseTempFile": return target.isUseTempFile();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..625e9734846
--- /dev/null
+++ b/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=ZipAggregationStrategy
+groupId=org.apache.camel
+artifactId=camel-zipfile
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Zip File
+projectDescription=Camel Zip file support
diff --git a/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/bean/ZipAggregationStrategy.json b/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/bean/ZipAggregationStrategy.json
new file mode 100644
index 00000000000..f7b20124fa4
--- /dev/null
+++ b/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/bean/ZipAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "ZipAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Zip Aggregation Strategy",
+    "description": "AggregationStrategy to zip together incoming messages into a zip file. Please note that this aggregation strategy requires eager completion check to work properly.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-zipfile",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "filePrefix": { "index": 0, "kind": "property", "displayName": "File Prefix", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the prefix that will be used when creating the ZIP filename." }, "fileSuffix": { "index": 1, "kind": "property", "displayName": "File Suffix", "required": false, "type": "object", "javaType": "or [...]
+  }
+}
+
diff --git a/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy b/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy
new file mode 100644
index 00000000000..94eabce9fd5
--- /dev/null
+++ b/components/camel-zipfile/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.zipfile.ZipAggregationStrategyConfigurer
diff --git a/components/camel-zipfile/src/main/java/org/apache/camel/processor/aggregate/zipfile/ZipAggregationStrategy.java b/components/camel-zipfile/src/main/java/org/apache/camel/processor/aggregate/zipfile/ZipAggregationStrategy.java
index 5b59f2eee7b..b7f05a312d3 100644
--- a/components/camel-zipfile/src/main/java/org/apache/camel/processor/aggregate/zipfile/ZipAggregationStrategy.java
+++ b/components/camel-zipfile/src/main/java/org/apache/camel/processor/aggregate/zipfile/ZipAggregationStrategy.java
@@ -36,6 +36,8 @@ import org.apache.camel.component.file.FileConsumer;
 import org.apache.camel.component.file.GenericFile;
 import org.apache.camel.component.file.GenericFileMessage;
 import org.apache.camel.component.file.GenericFileOperationFailedException;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.Synchronization;
 import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.util.FileUtil;
@@ -51,13 +53,26 @@ import org.apache.camel.util.FileUtil;
  * <b>Note:</b> Please note that this aggregation strategy requires eager completion check to work properly.
  * </p>
  */
+@Metadata(label = "bean",
+          description = "AggregationStrategy to zip together incoming messages into a zip file."
+                        + " Please note that this aggregation strategy requires eager completion check to work properly.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class ZipAggregationStrategy implements AggregationStrategy {
 
+    @Metadata(description = "Sets the prefix that will be used when creating the ZIP filename.")
     private String filePrefix;
+    @Metadata(description = "Sets the suffix that will be used when creating the ZIP filename.", defaultValue = "zip")
     private String fileSuffix = ".zip";
+    @Metadata(label = "advanced",
+              description = "If the incoming message is from a file, then the folder structure of said file can be preserved")
     private boolean preserveFolderStructure;
+    @Metadata(label = "advanced",
+              description = "Whether to use CamelFileName header for the filename instead of using unique message id")
     private boolean useFilenameHeader;
+    @Metadata(label = "advanced", description = "Whether to use temporary files for zip manipulations instead of memory.")
     private boolean useTempFile;
+    @Metadata(label = "advanced", description = "Sets the parent directory to use for writing temporary files")
     private File parentDir = new File(System.getProperty("java.io.tmpdir"));
 
     public ZipAggregationStrategy() {
@@ -150,6 +165,30 @@ public class ZipAggregationStrategy implements AggregationStrategy {
         this.parentDir = new File(parentDir);
     }
 
+    public boolean isPreserveFolderStructure() {
+        return preserveFolderStructure;
+    }
+
+    public void setPreserveFolderStructure(boolean preserveFolderStructure) {
+        this.preserveFolderStructure = preserveFolderStructure;
+    }
+
+    public boolean isUseTempFile() {
+        return useTempFile;
+    }
+
+    public void setUseTempFile(boolean useTempFile) {
+        this.useTempFile = useTempFile;
+    }
+
+    public boolean isUseFilenameHeader() {
+        return useFilenameHeader;
+    }
+
+    public void setUseFilenameHeader(boolean useFilenameHeader) {
+        this.useFilenameHeader = useFilenameHeader;
+    }
+
     @Override
     public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
         File zipFile;
diff --git a/core/camel-api/src/main/java/org/apache/camel/CatalogCamelContext.java b/core/camel-api/src/main/java/org/apache/camel/CatalogCamelContext.java
index c2f8c1b3b40..84063e4c6af 100644
--- a/core/camel-api/src/main/java/org/apache/camel/CatalogCamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/CatalogCamelContext.java
@@ -70,4 +70,11 @@ public interface CatalogCamelContext extends CamelContext {
      */
     String getEipParameterJsonSchema(String eipName) throws IOException;
 
+    /**
+     * Returns the JSON schema representation of the pojo bean parameters for the given bean name.
+     *
+     * @return the json or <tt>null</tt> if the pojo bean does not exist
+     */
+    String getPojoBeanParameterJsonSchema(String name) throws IOException;
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/catalog/JSonSchemaResolver.java b/core/camel-api/src/main/java/org/apache/camel/catalog/JSonSchemaResolver.java
index 7d04305e0f2..0027f93d1df 100644
--- a/core/camel-api/src/main/java/org/apache/camel/catalog/JSonSchemaResolver.java
+++ b/core/camel-api/src/main/java/org/apache/camel/catalog/JSonSchemaResolver.java
@@ -89,4 +89,12 @@ public interface JSonSchemaResolver {
      */
     String getMainJsonSchema();
 
+    /**
+     * Returns the pojo bean information as JSON format.
+     *
+     * @param  name the pojo bean name
+     * @return      model details in JSon
+     */
+    String getPojoBeanJSonSchema(String name);
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Configurer.java b/core/camel-api/src/main/java/org/apache/camel/spi/Configurer.java
index 0d78ec0d704..85da1c03b2c 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Configurer.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Configurer.java
@@ -47,4 +47,9 @@ public @interface Configurer {
      */
     boolean bootstrap() default false;
 
+    /**
+     * Whether to only include fields that are have @Metadata annotations.
+     */
+    boolean metadataOnly() default false;
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/RecoverableAggregationRepository.java b/core/camel-api/src/main/java/org/apache/camel/spi/RecoverableAggregationRepository.java
index a16093fde6c..44bbafa3456 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/RecoverableAggregationRepository.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/RecoverableAggregationRepository.java
@@ -48,9 +48,11 @@ public interface RecoverableAggregationRepository extends AggregationRepository
     /**
      * Sets the interval between recovery scans
      *
-     * @param interval the interval
-     * @param timeUnit the time unit
+     * @param      interval the interval
+     * @param      timeUnit the time unit
+     * @deprecated          use setRecoveryInterval
      */
+    @Deprecated
     void setRecoveryInterval(long interval, TimeUnit timeUnit);
 
     /**
@@ -65,7 +67,18 @@ public interface RecoverableAggregationRepository extends AggregationRepository
      *
      * @return the interval in millis
      */
-    long getRecoveryIntervalInMillis();
+    long getRecoveryInterval();
+
+    /**
+     * Gets the interval between recovery scans in millis.
+     *
+     * @return     the interval in millis
+     * @deprecated use getRecoveryInterval
+     */
+    @Deprecated
+    default long getRecoveryIntervalInMillis() {
+        return getRecoveryInterval();
+    }
 
     /**
      * Sets whether or not recovery is enabled
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 0bd5970c301..07f9e92d11b 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -1491,6 +1491,17 @@ public abstract class AbstractCamelContext extends BaseService
         return null;
     }
 
+    @Override
+    public String getPojoBeanParameterJsonSchema(String beanName) throws IOException {
+        String name = sanitizeFileName(beanName) + ".json";
+        String path = "META-INF/services/org/apache/camel/bean/" + name;
+        String inputStream = doLoadResource(beanName, path, "bean");
+        if (inputStream != null) {
+            return inputStream;
+        }
+        return null;
+    }
+
     // Helper methods
     // -----------------------------------------------------------------------
 
diff --git a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/AbstractCamelCatalog.java b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/AbstractCamelCatalog.java
index 6975cd34da0..ee2e66b0b1d 100644
--- a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/AbstractCamelCatalog.java
+++ b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/AbstractCamelCatalog.java
@@ -54,6 +54,7 @@ import org.apache.camel.tooling.model.JsonMapper;
 import org.apache.camel.tooling.model.LanguageModel;
 import org.apache.camel.tooling.model.MainModel;
 import org.apache.camel.tooling.model.OtherModel;
+import org.apache.camel.tooling.model.PojoBeanModel;
 import org.apache.camel.tooling.model.TransformerModel;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ReflectionHelper;
@@ -122,6 +123,15 @@ public abstract class AbstractCamelCatalog {
         return json != null ? JsonMapper.generateTransformerModel(json) : null;
     }
 
+    public PojoBeanModel pojoBeanModel(String name) {
+        String json = pojoBeanJSonSchema(name);
+        return json != null ? JsonMapper.generatePojoBeanModel(json) : null;
+    }
+
+    public String pojoBeanJSonSchema(String name) {
+        return getJSonSchemaResolver().getPojoBeanJSonSchema(name);
+    }
+
     public String devConsoleJSonSchema(String name) {
         return getJSonSchemaResolver().getDevConsoleJSonSchema(name);
     }
diff --git a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/CamelContextJSonSchemaResolver.java b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/CamelContextJSonSchemaResolver.java
index 8d32943cb44..a737401dd8f 100644
--- a/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/CamelContextJSonSchemaResolver.java
+++ b/core/camel-core-catalog/src/main/java/org/apache/camel/catalog/impl/CamelContextJSonSchemaResolver.java
@@ -98,6 +98,16 @@ public class CamelContextJSonSchemaResolver implements JSonSchemaResolver {
         return null;
     }
 
+    @Override
+    public String getPojoBeanJSonSchema(String name) {
+        try {
+            return camelContext.getPojoBeanParameterJsonSchema(name);
+        } catch (IOException e) {
+            // ignore
+        }
+        return null;
+    }
+
     @Override
     public String getModelJSonSchema(String name) {
         try {
diff --git a/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategyConfigurer.java b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..132ef2a13e5
--- /dev/null
+++ b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategyConfigurer.java
@@ -0,0 +1,35 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class GroupedBodyAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git a/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedExchangeAggregationStrategyConfigurer.java b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedExchangeAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..d59e0e119d1
--- /dev/null
+++ b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedExchangeAggregationStrategyConfigurer.java
@@ -0,0 +1,35 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class GroupedExchangeAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git a/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedMessageAggregationStrategyConfigurer.java b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedMessageAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..d70c0011492
--- /dev/null
+++ b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/GroupedMessageAggregationStrategyConfigurer.java
@@ -0,0 +1,35 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.GroupedMessageAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class GroupedMessageAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git a/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/MemoryAggregationRepositoryConfigurer.java b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/MemoryAggregationRepositoryConfigurer.java
new file mode 100644
index 00000000000..26a814696b5
--- /dev/null
+++ b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/MemoryAggregationRepositoryConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.MemoryAggregationRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class MemoryAggregationRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.MemoryAggregationRepository target = (org.apache.camel.processor.aggregate.MemoryAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "optimisticlocking":
+        case "OptimisticLocking": target.setOptimisticLocking(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "optimisticlocking":
+        case "OptimisticLocking": return boolean.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.MemoryAggregationRepository target = (org.apache.camel.processor.aggregate.MemoryAggregationRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "optimisticlocking":
+        case "OptimisticLocking": return target.isOptimisticLocking();
+        default: return null;
+        }
+    }
+}
+
diff --git a/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/StringAggregationStrategyConfigurer.java b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/StringAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..cf6de06c0f9
--- /dev/null
+++ b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/StringAggregationStrategyConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.StringAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class StringAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.StringAggregationStrategy target = (org.apache.camel.processor.aggregate.StringAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "delimiter":
+        case "Delimiter": target.setDelimiter(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "delimiter":
+        case "Delimiter": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.processor.aggregate.StringAggregationStrategy target = (org.apache.camel.processor.aggregate.StringAggregationStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "delimiter":
+        case "Delimiter": return target.getDelimiter();
+        default: return null;
+        }
+    }
+}
+
diff --git a/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/UseLatestAggregationStrategyConfigurer.java b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/UseLatestAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..9d7e11fd713
--- /dev/null
+++ b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/UseLatestAggregationStrategyConfigurer.java
@@ -0,0 +1,35 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class UseLatestAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git a/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategyConfigurer.java b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategyConfigurer.java
new file mode 100644
index 00000000000..3e0b4024d9f
--- /dev/null
+++ b/core/camel-core-processor/src/generated/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategyConfigurer.java
@@ -0,0 +1,35 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.processor.aggregate;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class UseOriginalAggregationStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        return false;
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        return null;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        return null;
+    }
+}
+
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..08e572c6577
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=GroupedBodyAggregationStrategy GroupedExchangeAggregationStrategy GroupedMessageAggregationStrategy MemoryAggregationRepository StringAggregationStrategy UseLatestAggregationStrategy UseOriginalAggregationStrategy
+groupId=org.apache.camel
+artifactId=camel-core-processor
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Core Processor
+projectDescription=Camel core processors
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedBodyAggregationStrategy.json b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedBodyAggregationStrategy.json
new file mode 100644
index 00000000000..10edccd31e1
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedBodyAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedBodyAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Body Aggregation Strategy",
+    "description": "Aggregate body of input Message into a single combined Exchange holding all the aggregated bodies in a List of type Object as the message body. This aggregation strategy can be used in combination with Splitter to batch messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedExchangeAggregationStrategy.json b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedExchangeAggregationStrategy.json
new file mode 100644
index 00000000000..7ba11aca0c4
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedExchangeAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedExchangeAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Exchange Aggregation Strategy",
+    "description": "Aggregate all Exchanges into a single combined Exchange holding all the aggregated exchanges in a List of Exchange as the message body. This aggregation strategy can be used in combination with Splitter to batch messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedMessageAggregationStrategy.json b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedMessageAggregationStrategy.json
new file mode 100644
index 00000000000..a03cad939d9
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/GroupedMessageAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "GroupedMessageAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.GroupedMessageAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Grouped Message Aggregation Strategy",
+    "description": "Aggregate all Message into a single combined Exchange holding all the aggregated messages in a List of Message as the message body. This aggregation strategy can be used in combination with Splitter to batch messages.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryAggregationRepository.json b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryAggregationRepository.json
new file mode 100644
index 00000000000..89401b1e5fe
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryAggregationRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "MemoryAggregationRepository",
+    "javaType": "org.apache.camel.processor.aggregate.MemoryAggregationRepository",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Memory Aggregation Repository",
+    "description": "A memory based AggregationRepository which stores Exchange in memory only.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "optimisticLocking": { "index": 0, "kind": "property", "displayName": "Optimistic Locking", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.MemoryAggregationRepository", "deprecated": false, "autowired": false, "secret": false, "description": "Whether to use optimistic locking" } }
+  }
+}
+
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/StringAggregationStrategy.json b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/StringAggregationStrategy.json
new file mode 100644
index 00000000000..b1b1279d2b3
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/StringAggregationStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "StringAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.StringAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "String Aggregation Strategy",
+    "description": "Aggregate result of pick expression into a single combined Exchange holding all the aggregated bodies in a String as the message body. This aggregation strategy can used in combination with Splitter to batch messages",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "delimiter": { "index": 0, "kind": "property", "displayName": "Delimiter", "required": false, "type": "object", "javaType": "org.apache.camel.processor.aggregate.StringAggregationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "Delimiter used for joining strings together." } }
+  }
+}
+
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/UseLatestAggregationStrategy.json b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/UseLatestAggregationStrategy.json
new file mode 100644
index 00000000000..5d73c66d791
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/UseLatestAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "UseLatestAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.UseLatestAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Use Latest Aggregation Strategy",
+    "description": "An AggregationStrategy which just uses the latest exchange which is useful for status messages where old status messages have no real value. Another example is things like market data prices, where old stock prices are not that relevant, only the current price is.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/UseOriginalAggregationStrategy.json b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/UseOriginalAggregationStrategy.json
new file mode 100644
index 00000000000..7ab066f5d79
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean/UseOriginalAggregationStrategy.json
@@ -0,0 +1,15 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "UseOriginalAggregationStrategy",
+    "javaType": "org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy",
+    "interfaceType": "org.apache.camel.AggregationStrategy",
+    "title": "Use Original Aggregation Strategy",
+    "description": "An AggregationStrategy which just uses the original exchange which can be needed when you want to preserve the original Exchange. For example when splitting an Exchange and then you may want to keep routing using the original Exchange.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-core-processor",
+    "version": "4.5.0-SNAPSHOT"
+  }
+}
+
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/beans.properties b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/beans.properties
new file mode 100644
index 00000000000..c8e1f79c503
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/beans.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+beans=UseLatestAggregationStrategy UseOriginalAggregationStrategy
+groupId=org.apache.camel
+artifactId=camel-core-processor
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Core Processor
+projectDescription=Camel core processors
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategy b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategy
new file mode 100644
index 00000000000..c9e77f377c1
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategyConfigurer
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy
new file mode 100644
index 00000000000..8750c6f5241
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategyConfigurer
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedMessageAggregationStrategy b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedMessageAggregationStrategy
new file mode 100644
index 00000000000..ee8dc6c5a79
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.GroupedMessageAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.GroupedMessageAggregationStrategyConfigurer
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.MemoryAggregationRepository b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.MemoryAggregationRepository
new file mode 100644
index 00000000000..68b903464bb
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.MemoryAggregationRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.MemoryAggregationRepositoryConfigurer
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.StringAggregationStrategy b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.StringAggregationStrategy
new file mode 100644
index 00000000000..73a3ae530d9
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.StringAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.StringAggregationStrategyConfigurer
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.UseLatestAggregationStrategy b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.UseLatestAggregationStrategy
new file mode 100644
index 00000000000..0d550271469
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.UseLatestAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.UseLatestAggregationStrategyConfigurer
diff --git a/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy
new file mode 100644
index 00000000000..56f1c06e473
--- /dev/null
+++ b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.processor.aggregate.UseOriginalAggregationStrategyConfigurer
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/AggregateProcessor.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/AggregateProcessor.java
index a460afa27b8..30a9ea84112 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/AggregateProcessor.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/AggregateProcessor.java
@@ -1554,7 +1554,7 @@ public class AggregateProcessor extends AsyncProcessorSupport
         if (isRecoverableRepository()) {
             RecoverableAggregationRepository recoverable = (RecoverableAggregationRepository) aggregationRepository;
             if (recoverable.isUseRecovery()) {
-                long interval = recoverable.getRecoveryIntervalInMillis();
+                long interval = recoverable.getRecoveryInterval();
                 if (interval <= 0) {
                     throw new IllegalArgumentException(
                             "AggregationRepository has recovery enabled and the RecoveryInterval option must be a positive number, was: "
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategy.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategy.java
index ac5175ed237..4576a5e4da2 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategy.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategy.java
@@ -20,6 +20,8 @@ import java.util.List;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 
 /**
  * Aggregate body of input {@link Message} into a single combined Exchange holding all the aggregated bodies in a
@@ -27,6 +29,12 @@ import org.apache.camel.Message;
  *
  * This aggregation strategy can used in combination with {@link org.apache.camel.processor.Splitter} to batch messages
  */
+@Metadata(label = "bean",
+          description = "Aggregate body of input Message into a single combined Exchange holding all the aggregated bodies in a List"
+                        + " of type Object as the message body. This aggregation strategy can be used in combination with"
+                        + " Splitter to batch messages.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class GroupedBodyAggregationStrategy extends AbstractListAggregationStrategy<Object> {
 
     @Override
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedExchangeAggregationStrategy.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedExchangeAggregationStrategy.java
index aa1f2b17392..8ba5c0c5b9c 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedExchangeAggregationStrategy.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedExchangeAggregationStrategy.java
@@ -19,6 +19,8 @@ package org.apache.camel.processor.aggregate;
 import java.util.List;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.DefaultExchange;
 
 /**
@@ -28,6 +30,12 @@ import org.apache.camel.support.DefaultExchange;
  * <b>Important:</b> This strategy is not to be used with the
  * <a href="http://camel.apache.org/content-enricher.html">Content Enricher</a> EIP which is enrich or pollEnrich.
  */
+@Metadata(label = "bean",
+          description = "Aggregate all Exchanges into a single combined Exchange holding all the aggregated exchanges in a List"
+                        + " of Exchange as the message body. This aggregation strategy can be used in combination with"
+                        + " Splitter to batch messages.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class GroupedExchangeAggregationStrategy extends AbstractListAggregationStrategy<Exchange> {
 
     @Override
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedMessageAggregationStrategy.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedMessageAggregationStrategy.java
index ef47d5d0a02..338cc5bda7b 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedMessageAggregationStrategy.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedMessageAggregationStrategy.java
@@ -20,6 +20,8 @@ import java.util.List;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.DefaultExchange;
 
 /**
@@ -29,6 +31,12 @@ import org.apache.camel.support.DefaultExchange;
  * This aggregation strategy can be used in combination with {@link org.apache.camel.processor.Splitter} to batch
  * messages
  */
+@Metadata(label = "bean",
+          description = "Aggregate all Message into a single combined Exchange holding all the aggregated messages in a List"
+                        + " of Message as the message body. This aggregation strategy can be used in combination with"
+                        + " Splitter to batch messages.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class GroupedMessageAggregationStrategy extends AbstractListAggregationStrategy<Message> {
 
     @Override
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/MemoryAggregationRepository.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/MemoryAggregationRepository.java
index f2c594486ba..118724bf8b4 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/MemoryAggregationRepository.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/MemoryAggregationRepository.java
@@ -23,6 +23,8 @@ import java.util.concurrent.ConcurrentMap;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.OptimisticLockingAggregationRepository;
 import org.apache.camel.support.service.ServiceSupport;
 
@@ -31,9 +33,15 @@ import org.apache.camel.support.service.ServiceSupport;
  *
  * Supports both optimistic locking and non-optimistic locking modes. Defaults to non-optimistic locking mode.
  */
+@Metadata(label = "bean",
+          description = "A memory based AggregationRepository which stores Exchange in memory only.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class MemoryAggregationRepository extends ServiceSupport implements OptimisticLockingAggregationRepository {
     private final ConcurrentMap<String, Exchange> cache = new ConcurrentHashMap<>();
-    private final boolean optimisticLocking;
+
+    @Metadata(description = "Whether to use optimistic locking")
+    private boolean optimisticLocking;
 
     public MemoryAggregationRepository() {
         this(false);
@@ -43,6 +51,14 @@ public class MemoryAggregationRepository extends ServiceSupport implements Optim
         this.optimisticLocking = optimisticLocking;
     }
 
+    public boolean isOptimisticLocking() {
+        return optimisticLocking;
+    }
+
+    public void setOptimisticLocking(boolean optimisticLocking) {
+        this.optimisticLocking = optimisticLocking;
+    }
+
     @Override
     public Exchange add(CamelContext camelContext, String key, Exchange oldExchange, Exchange newExchange) {
         if (!optimisticLocking) {
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/StringAggregationStrategy.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/StringAggregationStrategy.java
index ed08e6a0a8b..83dd161bd90 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/StringAggregationStrategy.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/StringAggregationStrategy.java
@@ -20,6 +20,8 @@ import org.apache.camel.AggregationStrategy;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePropertyKey;
 import org.apache.camel.Expression;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.builder.ExpressionBuilder;
 
 /**
@@ -28,11 +30,33 @@ import org.apache.camel.support.builder.ExpressionBuilder;
  *
  * This aggregation strategy can used in combination with {@link org.apache.camel.processor.Splitter} to batch messages
  */
+@Metadata(label = "bean",
+          description = "Aggregate result of pick expression into a single combined Exchange holding all the aggregated bodies in a"
+                        + " String as the message body. This aggregation strategy can used in combination with Splitter to batch messages",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class StringAggregationStrategy implements AggregationStrategy {
 
+    @Metadata(description = "Delimiter used for joining strings together.")
     private String delimiter = "";
     private Expression pickExpression = ExpressionBuilder.bodyExpression();
 
+    public String getDelimiter() {
+        return delimiter;
+    }
+
+    public void setDelimiter(String delimiter) {
+        this.delimiter = delimiter;
+    }
+
+    public Expression getPickExpression() {
+        return pickExpression;
+    }
+
+    public void setPickExpression(Expression pickExpression) {
+        this.pickExpression = pickExpression;
+    }
+
     /**
      * Set delimiter used for joining aggregated String
      *
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseLatestAggregationStrategy.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseLatestAggregationStrategy.java
index d43a6a7fa76..be388dad6a6 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseLatestAggregationStrategy.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseLatestAggregationStrategy.java
@@ -19,12 +19,20 @@ package org.apache.camel.processor.aggregate;
 import org.apache.camel.AggregationStrategy;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePropertyKey;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 
 /**
  * An {@link AggregationStrategy} which just uses the latest exchange which is useful for status messages where old
  * status messages have no real value. Another example is things like market data prices, where old stock prices are not
  * that relevant, only the current price is.
  */
+@Metadata(label = "bean",
+          description = "An AggregationStrategy which just uses the latest exchange which is useful for status messages where old"
+                        + " status messages have no real value. Another example is things like market data prices, where old stock prices are not"
+                        + " that relevant, only the current price is.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class UseLatestAggregationStrategy implements AggregationStrategy {
 
     @Override
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.java
index 4fa8dc75f57..1abb39047ce 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/UseOriginalAggregationStrategy.java
@@ -18,6 +18,8 @@ package org.apache.camel.processor.aggregate;
 
 import org.apache.camel.AggregationStrategy;
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.Metadata;
 
 /**
  * An {@link AggregationStrategy} which just uses the original exchange which can be needed when you want to preserve
@@ -26,6 +28,12 @@ import org.apache.camel.Exchange;
  *
  * @see org.apache.camel.processor.Splitter
  */
+@Metadata(label = "bean",
+          description = "An AggregationStrategy which just uses the original exchange which can be needed when you want to preserve"
+                        + " the original Exchange. For example when splitting an Exchange and then you may want to keep routing using the"
+                        + " original Exchange.",
+          annotations = { "interfaceName=org.apache.camel.AggregationStrategy" })
+@Configurer(metadataOnly = true)
 public class UseOriginalAggregationStrategy implements AggregationStrategy {
 
     private final Exchange original;
diff --git a/core/camel-main/src/test/java/org/apache/camel/main/FileIdempotentRepositoryConfigurerTest.java b/core/camel-main/src/test/java/org/apache/camel/main/FileIdempotentRepositoryConfigurerTest.java
new file mode 100644
index 00000000000..459b5157e1b
--- /dev/null
+++ b/core/camel-main/src/test/java/org/apache/camel/main/FileIdempotentRepositoryConfigurerTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.main;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.support.PluginHelper;
+import org.apache.camel.support.PropertyBindingSupport;
+import org.apache.camel.support.processor.idempotent.FileIdempotentRepository;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class FileIdempotentRepositoryConfigurerTest {
+
+    @Test
+    public void testReflectionFree() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+
+        BeanIntrospection bi = PluginHelper.getBeanIntrospection(context);
+        bi.setExtendedStatistics(true);
+
+        context.start();
+
+        FileIdempotentRepository target = new FileIdempotentRepository();
+
+        boolean hit = PropertyBindingSupport.build()
+                .withCamelContext(context)
+                .withTarget(target)
+                .withReflection(false)
+                .withIgnoreCase(true)
+                .withProperty("dropOldestFileStore", "123")
+                .withProperty("maxFileStoreSize", "2000")
+                .withRemoveParameters(true).bind();
+
+        assertTrue(hit);
+
+        assertEquals(123, target.getDropOldestFileStore());
+        assertEquals(2000, target.getMaxFileStoreSize());
+
+        // will auto detect generated configurer so no reflection in use
+        assertEquals(0, bi.getInvokedCounter());
+
+        context.stop();
+    }
+
+}
diff --git a/core/camel-support/src/generated/java/org/apache/camel/support/DefaultHeaderFilterStrategyConfigurer.java b/core/camel-support/src/generated/java/org/apache/camel/support/DefaultHeaderFilterStrategyConfigurer.java
new file mode 100644
index 00000000000..7577bc42fc1
--- /dev/null
+++ b/core/camel-support/src/generated/java/org/apache/camel/support/DefaultHeaderFilterStrategyConfigurer.java
@@ -0,0 +1,90 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.support;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.DefaultHeaderFilterStrategy;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class DefaultHeaderFilterStrategyConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.support.DefaultHeaderFilterStrategy target = (org.apache.camel.support.DefaultHeaderFilterStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allownullvalues":
+        case "AllowNullValues": target.setAllowNullValues(property(camelContext, boolean.class, value)); return true;
+        case "caseinsensitive":
+        case "CaseInsensitive": target.setCaseInsensitive(property(camelContext, boolean.class, value)); return true;
+        case "filteronmatch":
+        case "FilterOnMatch": target.setFilterOnMatch(property(camelContext, boolean.class, value)); return true;
+        case "infilter":
+        case "InFilter": target.setInFilter(property(camelContext, java.util.Set.class, value)); return true;
+        case "lowercase":
+        case "LowerCase": target.setLowerCase(property(camelContext, boolean.class, value)); return true;
+        case "outfilter":
+        case "OutFilter": target.setOutFilter(property(camelContext, java.util.Set.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allownullvalues":
+        case "AllowNullValues": return boolean.class;
+        case "caseinsensitive":
+        case "CaseInsensitive": return boolean.class;
+        case "filteronmatch":
+        case "FilterOnMatch": return boolean.class;
+        case "infilter":
+        case "InFilter": return java.util.Set.class;
+        case "lowercase":
+        case "LowerCase": return boolean.class;
+        case "outfilter":
+        case "OutFilter": return java.util.Set.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.support.DefaultHeaderFilterStrategy target = (org.apache.camel.support.DefaultHeaderFilterStrategy) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allownullvalues":
+        case "AllowNullValues": return target.isAllowNullValues();
+        case "caseinsensitive":
+        case "CaseInsensitive": return target.isCaseInsensitive();
+        case "filteronmatch":
+        case "FilterOnMatch": return target.isFilterOnMatch();
+        case "infilter":
+        case "InFilter": return target.getInFilter();
+        case "lowercase":
+        case "LowerCase": return target.isLowerCase();
+        case "outfilter":
+        case "OutFilter": return target.getOutFilter();
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "infilter":
+        case "InFilter": return java.lang.String.class;
+        case "outfilter":
+        case "OutFilter": return java.lang.String.class;
+        default: return null;
+        }
+    }
+}
+
diff --git a/core/camel-support/src/generated/java/org/apache/camel/support/processor/idempotent/FileIdempotentRepositoryConfigurer.java b/core/camel-support/src/generated/java/org/apache/camel/support/processor/idempotent/FileIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..2f828cd9aee
--- /dev/null
+++ b/core/camel-support/src/generated/java/org/apache/camel/support/processor/idempotent/FileIdempotentRepositoryConfigurer.java
@@ -0,0 +1,67 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.support.processor.idempotent;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.processor.idempotent.FileIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class FileIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.support.processor.idempotent.FileIdempotentRepository target = (org.apache.camel.support.processor.idempotent.FileIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachesize":
+        case "CacheSize": target.setCacheSize(property(camelContext, int.class, value)); return true;
+        case "dropoldestfilestore":
+        case "DropOldestFileStore": target.setDropOldestFileStore(property(camelContext, long.class, value)); return true;
+        case "filestore":
+        case "FileStore": target.setFileStore(property(camelContext, java.io.File.class, value)); return true;
+        case "maxfilestoresize":
+        case "MaxFileStoreSize": target.setMaxFileStoreSize(property(camelContext, long.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachesize":
+        case "CacheSize": return int.class;
+        case "dropoldestfilestore":
+        case "DropOldestFileStore": return long.class;
+        case "filestore":
+        case "FileStore": return java.io.File.class;
+        case "maxfilestoresize":
+        case "MaxFileStoreSize": return long.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.support.processor.idempotent.FileIdempotentRepository target = (org.apache.camel.support.processor.idempotent.FileIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachesize":
+        case "CacheSize": return target.getCacheSize();
+        case "dropoldestfilestore":
+        case "DropOldestFileStore": return target.getDropOldestFileStore();
+        case "filestore":
+        case "FileStore": return target.getFileStore();
+        case "maxfilestoresize":
+        case "MaxFileStoreSize": return target.getMaxFileStoreSize();
+        default: return null;
+        }
+    }
+}
+
diff --git a/core/camel-support/src/generated/java/org/apache/camel/support/processor/idempotent/MemoryIdempotentRepositoryConfigurer.java b/core/camel-support/src/generated/java/org/apache/camel/support/processor/idempotent/MemoryIdempotentRepositoryConfigurer.java
new file mode 100644
index 00000000000..bafc4b82526
--- /dev/null
+++ b/core/camel-support/src/generated/java/org/apache/camel/support/processor/idempotent/MemoryIdempotentRepositoryConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.support.processor.idempotent;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class MemoryIdempotentRepositoryConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository target = (org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachesize":
+        case "CacheSize": target.setCacheSize(property(camelContext, int.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachesize":
+        case "CacheSize": return int.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository target = (org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "cachesize":
+        case "CacheSize": return target.getCacheSize();
+        default: return null;
+        }
+    }
+}
+
diff --git a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean.properties b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
new file mode 100644
index 00000000000..25ce5d4b2f9
--- /dev/null
+++ b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+bean=DefaultHeaderFilterStrategy FileIdempotentRepository MemoryIdempotentRepository
+groupId=org.apache.camel
+artifactId=camel-support
+version=4.5.0-SNAPSHOT
+projectName=Camel :: Support
+projectDescription=The Camel Support
diff --git a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/DefaultHeaderFilterStrategy.json b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/DefaultHeaderFilterStrategy.json
new file mode 100644
index 00000000000..db72da32c2e
--- /dev/null
+++ b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/DefaultHeaderFilterStrategy.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "DefaultHeaderFilterStrategy",
+    "javaType": "org.apache.camel.support.DefaultHeaderFilterStrategy",
+    "interfaceType": "org.apache.camel.spi.HeaderFilterStrategy",
+    "title": "Default Header Filter Strategy",
+    "description": "The default header filtering strategy. Users can configure which headers is allowed or denied.",
+    "deprecated": true,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-support",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "inFilter": { "index": 0, "kind": "property", "displayName": "In Filter", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the in direction filter set. The in direction is referred to copying headers from an external message to a Camel message. Multiple patterns can be separated by comma" }, "outFilter": { "index": 1, "kind": "property", "displayName": "Out Filter", "req [...]
+  }
+}
+
diff --git a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/FileIdempotentRepository.json b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/FileIdempotentRepository.json
new file mode 100644
index 00000000000..b90fd10b9f5
--- /dev/null
+++ b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/FileIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "FileIdempotentRepository",
+    "javaType": "org.apache.camel.support.processor.idempotent.FileIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "File Idempotent Repository",
+    "description": "A file based IdempotentRepository.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-support",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "fileStore": { "index": 0, "kind": "property", "displayName": "File Store", "required": true, "type": "object", "javaType": "org.apache.camel.support.processor.idempotent.FileIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "description": "File name of the repository (incl directory)" }, "maxFileStoreSize": { "index": 1, "kind": "property", "displayName": "Max File Store Size", "required": false, "type": "object", "javaType": "org.apach [...]
+  }
+}
+
diff --git a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
new file mode 100644
index 00000000000..a70bbdcdf2e
--- /dev/null
+++ b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
@@ -0,0 +1,16 @@
+{
+  "bean": {
+    "kind": "bean",
+    "name": "MemoryIdempotentRepository",
+    "javaType": "org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository",
+    "interfaceType": "org.apache.camel.spi.IdempotentRepository",
+    "title": "Memory Idempotent Repository",
+    "description": "A memory based IdempotentRepository.",
+    "deprecated": false,
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-support",
+    "version": "4.5.0-SNAPSHOT",
+    "properties": { "cacheSize": { "index": 0, "kind": "property", "displayName": "Cache Size", "required": false, "type": "object", "javaType": "org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "description": "Maximum elements that can be stored in-memory" } }
+  }
+}
+
diff --git a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.DefaultHeaderFilterStrategy b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.DefaultHeaderFilterStrategy
new file mode 100644
index 00000000000..fb11827af4c
--- /dev/null
+++ b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.DefaultHeaderFilterStrategy
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.support.DefaultHeaderFilterStrategyConfigurer
diff --git a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.processor.idempotent.FileIdempotentRepository b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.processor.idempotent.FileIdempotentRepository
new file mode 100644
index 00000000000..c78a2e790d6
--- /dev/null
+++ b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.processor.idempotent.FileIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.support.processor.idempotent.FileIdempotentRepositoryConfigurer
diff --git a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository
new file mode 100644
index 00000000000..0cc3f68c3e1
--- /dev/null
+++ b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.support.processor.idempotent.MemoryIdempotentRepositoryConfigurer
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java
index 7a99e29ab16..5570e4953db 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java
@@ -22,18 +22,24 @@ import java.util.Set;
 import java.util.regex.Pattern;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.spi.Metadata;
 
 /**
  * The default header filtering strategy. Users can configure filter by setting filter set and/or setting a regular
  * expression. Subclass can add extended filter logic in
  * {@link #extendedFilter(org.apache.camel.spi.HeaderFilterStrategy.Direction, String, Object, org.apache.camel.Exchange)}
- *
+ * <p>
  * Filters are associated with directions (in or out). "In" direction is referred to propagating headers "to" Camel
  * message. The "out" direction is opposite which is referred to propagating headers from Camel message to a native
  * message like JMS and CXF message. You can see example of DefaultHeaderFilterStrategy are being extended and invoked
  * in camel-jms and camel-cxf components.
  */
+@Metadata(label = "bean",
+          description = "The default header filtering strategy. Users can configure which headers is allowed or denied.",
+          annotations = { "interfaceName=org.apache.camel.spi.HeaderFilterStrategy" })
+@Configurer(metadataOnly = true)
 public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
 
     /**
@@ -49,17 +55,35 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
      */
     public static final String[] CAMEL_FILTER_STARTS_WITH = new String[] { "Camel", "camel", "org.apache.camel." };
 
+    @Metadata(javaType = "java.lang.String",
+              description = "Sets the in direction filter set. The in direction is referred to copying headers from an external message to a Camel message."
+                            + " Multiple patterns can be separated by comma")
     private Set<String> inFilter;
     private Pattern inFilterPattern;
     private String[] inFilterStartsWith;
 
+    @Metadata(javaType = "java.lang.String",
+              description = "Sets the out direction filter set. The out direction is referred to copying headers from a Camel message to an external message."
+                            + " Multiple patterns can be separated by comma")
     private Set<String> outFilter;
     private Pattern outFilterPattern;
     private String[] outFilterStartsWith;
 
+    @Metadata(label = "advanced", defaultValue = "false",
+              description = "Whether header names should be converted to lower case before checking it with the filter Set."
+                            + " It does not affect filtering using regular expression pattern.")
     private boolean lowerCase;
+    @Metadata(label = "advanced", defaultValue = "false",
+              description = "Whether to allow null values. By default a header is skipped if its value is null. Setting this to true will preserve the header.")
     private boolean allowNullValues;
+    @Metadata(label = "advanced", defaultValue = "false",
+              description = "Sets the caseInsensitive property which is a boolean to determine whether header names should be case insensitive"
+                            + " when checking it with the filter set. It does not affect filtering using regular expression pattern.")
     private boolean caseInsensitive;
+    @Metadata(label = "advanced", defaultValue = "true",
+              description = "Sets what to do when a pattern or filter set is matched."
+                            + " When set to true, a match will filter out the header. This is the default value for backwards compatibility."
+                            + " When set to false, the pattern or filter will indicate that the header must be kept; anything not matched will be filtered (skipped).")
     private boolean filterOnMatch = true; // defaults to the previous behaviour
 
     @Override
@@ -96,6 +120,12 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
         outFilter = value;
     }
 
+    public void setOutFilter(String value) {
+        if (value != null) {
+            this.outFilter = Set.of(value.split(","));
+        }
+    }
+
     /**
      * Sets the "out" direction filter by starts with pattern. The "out" direction is referred to copying headers from a
      * Camel message to an external message.
@@ -166,6 +196,12 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
         inFilter = value;
     }
 
+    public void setInFilter(String value) {
+        if (value != null) {
+            this.inFilter = Set.of(value.split(","));
+        }
+    }
+
     /**
      * Sets the "in" direction filter by starts with pattern. The "in" direction is referred to copying headers from an
      * external message to a Camel message.
@@ -255,7 +291,7 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
 
     /**
      * Whether to allow null values.
-     *
+     * <p>
      * By default a header is skipped if its value is null. Setting this to true will preserve the header.
      */
     public void setAllowNullValues(boolean value) {
@@ -269,9 +305,9 @@ public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
     /**
      * Sets the filterOnMatch property which is a boolean to determine what to do when a pattern or filter set is
      * matched.
-     *
+     * <p>
      * When set to true, a match will filter out the header. This is the default value for backwards compatibility.
-     *
+     * <p>
      * When set to false, the pattern or filter will indicate that the header must be kept; anything not matched will be
      * filtered (skipped).
      *
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/processor/idempotent/FileIdempotentRepository.java b/core/camel-support/src/main/java/org/apache/camel/support/processor/idempotent/FileIdempotentRepository.java
index 085b4da115b..1737d23440d 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/processor/idempotent/FileIdempotentRepository.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/processor/idempotent/FileIdempotentRepository.java
@@ -28,7 +28,9 @@ import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.LRUCache;
 import org.apache.camel.support.LRUCacheFactory;
 import org.apache.camel.support.service.ServiceSupport;
@@ -50,18 +52,27 @@ import org.slf4j.LoggerFactory;
  * {@link #getDropOldestFileStore()} (is default 1000) number of entries from the file store is dropped to reduce the
  * file store and make room for newer entries.
  */
+@Metadata(label = "bean",
+          description = "A file based IdempotentRepository.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 @ManagedResource(description = "File based idempotent repository")
 public class FileIdempotentRepository extends ServiceSupport implements IdempotentRepository {
 
     private static final Logger LOG = LoggerFactory.getLogger(FileIdempotentRepository.class);
-
     private static final String STORE_DELIMITER = "\n";
 
     private final AtomicBoolean init = new AtomicBoolean();
-
     private Map<String, Object> cache;
+
+    @Metadata(description = "File name of the repository (incl directory)", required = true)
     private File fileStore;
+    @Metadata(description = "The maximum file size for the file store in bytes. The default value is 32mb",
+              defaultValue = "" + 32 * 1024 * 1000L)
     private long maxFileStoreSize = 32 * 1024 * 1000L; // 32mb store file
+    @Metadata(description = "Sets the number of oldest entries to drop from the file store when the maximum capacity is hit to reduce disk"
+                            + " space to allow room for new entries.",
+              defaultValue = "1000")
     private long dropOldestFileStore = 1000;
 
     public FileIdempotentRepository() {
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/processor/idempotent/MemoryIdempotentRepository.java b/core/camel-support/src/main/java/org/apache/camel/support/processor/idempotent/MemoryIdempotentRepository.java
index 5a8cf516f40..64ad2f7d7a7 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/processor/idempotent/MemoryIdempotentRepository.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/processor/idempotent/MemoryIdempotentRepository.java
@@ -21,7 +21,9 @@ import java.util.Map;
 import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedOperation;
 import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.spi.Configurer;
 import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.LRUCache;
 import org.apache.camel.support.LRUCacheFactory;
 import org.apache.camel.support.service.ServiceSupport;
@@ -31,9 +33,15 @@ import org.apache.camel.support.service.ServiceSupport;
  * <p/>
  * Care should be taken to use a suitable underlying {@link Map} to avoid this class being a memory leak.
  */
+@Metadata(label = "bean",
+          description = "A memory based IdempotentRepository.",
+          annotations = { "interfaceName=org.apache.camel.spi.IdempotentRepository" })
+@Configurer(metadataOnly = true)
 @ManagedResource(description = "Memory based idempotent repository")
 public class MemoryIdempotentRepository extends ServiceSupport implements IdempotentRepository {
     private Map<String, Object> cache;
+
+    @Metadata(description = "Maximum elements that can be stored in-memory", defaultValue = "1000")
     private int cacheSize;
 
     public MemoryIdempotentRepository() {
diff --git a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/ModelJSonSchemaResolver.java b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/ModelJSonSchemaResolver.java
index f9496c19c95..3f6bd6eb974 100644
--- a/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/ModelJSonSchemaResolver.java
+++ b/core/camel-yaml-io/src/main/java/org/apache/camel/yaml/io/ModelJSonSchemaResolver.java
@@ -64,6 +64,11 @@ class ModelJSonSchemaResolver implements JSonSchemaResolver {
         throw new UnsupportedOperationException("Only getModelJSonSchema is in use");
     }
 
+    @Override
+    public String getPojoBeanJSonSchema(String name) {
+        throw new UnsupportedOperationException("Only getModelJSonSchema is in use");
+    }
+
     @Override
     public String getModelJSonSchema(String name) {
         try {
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc
index 09e9b724834..afc5faf70c0 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc
@@ -256,3 +256,13 @@ Upgraded Apache Shiro from 1.13 to 2.0.
 
 Upgraded to Twilio 10.1.0 which removed `call-feedback` and `call-feedback-summary` from the available APIs,
 to use from Camel.
+
+=== camel-elasticsearch / camel-opensearch
+
+The class `BulkRequestAggregationStrategy` has been renamed to `OpensearchBulkRequestAggregationStrategy`
+The class `BulkRequestAggregationStrategy` has been renamed to `ElasticsearchBulkRequestAggregationStrategy`
+
+=== camel-spring-redis
+
+The class `RedisIdempotentRepository` has been renamed to `SpringRedisIdempotentRepository`
+The class `RedisStringIdempotentRepository` has been renamed to `SpringRedisStringIdempotentRepository`
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
index 9cdc27b4aab..167b16cdc17 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/ComponentsBuilderFactory.java
@@ -2781,7 +2781,7 @@ public interface ComponentsBuilderFactory {
     }
     /**
      * Langchain4j Embeddings (camel-langchain-embeddings)
-     * Langchain4j Embeddings
+     * Perform operations on the Qdrant Vector Database.
      * 
      * Category: ai
      * Since: 4.5
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/LangchainEmbeddingsComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/LangchainEmbeddingsComponentBuilderFactory.java
index 9ac552400b8..7e9152c0822 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/LangchainEmbeddingsComponentBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/LangchainEmbeddingsComponentBuilderFactory.java
@@ -23,7 +23,7 @@ import org.apache.camel.builder.component.ComponentBuilder;
 import org.apache.camel.component.langchain.embeddings.LangchainEmbeddingsComponent;
 
 /**
- * Langchain4j Embeddings
+ * Perform operations on the Qdrant Vector Database.
  * 
  * Generated by camel-package-maven-plugin - do not edit this file!
  */
@@ -32,7 +32,7 @@ public interface LangchainEmbeddingsComponentBuilderFactory {
 
     /**
      * Langchain4j Embeddings (camel-langchain-embeddings)
-     * Langchain4j Embeddings
+     * Perform operations on the Qdrant Vector Database.
      * 
      * Category: ai
      * Since: 4.5
diff --git a/dsl/camel-componentdsl/src/generated/resources/metadata.json b/dsl/camel-componentdsl/src/generated/resources/metadata.json
index 07ad40f8e0a..9a632937ed2 100644
--- a/dsl/camel-componentdsl/src/generated/resources/metadata.json
+++ b/dsl/camel-componentdsl/src/generated/resources/metadata.json
@@ -4780,7 +4780,7 @@
     "kind": "component",
     "name": "langchain-embeddings",
     "title": "Langchain4j Embeddings",
-    "description": "Langchain4j Embeddings",
+    "description": "Perform operations on the Qdrant Vector Database.",
     "deprecated": false,
     "firstVersion": "4.5.0",
     "label": "ai",
@@ -4788,7 +4788,7 @@
     "supportLevel": "Preview",
     "groupId": "org.apache.camel",
     "artifactId": "camel-langchain-embeddings",
-    "version": "4.5.0-SNAPSHOT",
+    "version": "4.4.0-SNAPSHOT",
     "scheme": "langchain-embeddings",
     "extendsScheme": "",
     "syntax": "langchain-embeddings:embeddingId",
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/JCacheEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/JCacheEndpointBuilderFactory.java
index 278d80fb8b7..df0ccab3d9d 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/JCacheEndpointBuilderFactory.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/JCacheEndpointBuilderFactory.java
@@ -43,40 +43,6 @@ public interface JCacheEndpointBuilderFactory {
         default AdvancedJCacheEndpointConsumerBuilder advanced() {
             return (AdvancedJCacheEndpointConsumerBuilder) this;
         }
-        /**
-         * A Configuration for the Cache.
-         * 
-         * The option is a:
-         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
-         * type.
-         * 
-         * Group: common
-         * 
-         * @param cacheConfiguration the value to set
-         * @return the dsl builder
-         */
-        default JCacheEndpointConsumerBuilder cacheConfiguration(
-                javax.cache.configuration.Configuration cacheConfiguration) {
-            doSetProperty("cacheConfiguration", cacheConfiguration);
-            return this;
-        }
-        /**
-         * A Configuration for the Cache.
-         * 
-         * The option will be converted to a
-         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
-         * type.
-         * 
-         * Group: common
-         * 
-         * @param cacheConfiguration the value to set
-         * @return the dsl builder
-         */
-        default JCacheEndpointConsumerBuilder cacheConfiguration(
-                String cacheConfiguration) {
-            doSetProperty("cacheConfiguration", cacheConfiguration);
-            return this;
-        }
         /**
          * The Properties for the javax.cache.spi.CachingProvider to create the
          * CacheManager.
@@ -551,6 +517,40 @@ public interface JCacheEndpointBuilderFactory {
             doSetProperty("exchangePattern", exchangePattern);
             return this;
         }
+        /**
+         * A Configuration for the Cache.
+         * 
+         * The option is a:
+         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param cacheConfiguration the value to set
+         * @return the dsl builder
+         */
+        default AdvancedJCacheEndpointConsumerBuilder cacheConfiguration(
+                javax.cache.configuration.Configuration cacheConfiguration) {
+            doSetProperty("cacheConfiguration", cacheConfiguration);
+            return this;
+        }
+        /**
+         * A Configuration for the Cache.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param cacheConfiguration the value to set
+         * @return the dsl builder
+         */
+        default AdvancedJCacheEndpointConsumerBuilder cacheConfiguration(
+                String cacheConfiguration) {
+            doSetProperty("cacheConfiguration", cacheConfiguration);
+            return this;
+        }
         /**
          * The CacheLoader factory.
          * 
@@ -728,40 +728,6 @@ public interface JCacheEndpointBuilderFactory {
         default AdvancedJCacheEndpointProducerBuilder advanced() {
             return (AdvancedJCacheEndpointProducerBuilder) this;
         }
-        /**
-         * A Configuration for the Cache.
-         * 
-         * The option is a:
-         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
-         * type.
-         * 
-         * Group: common
-         * 
-         * @param cacheConfiguration the value to set
-         * @return the dsl builder
-         */
-        default JCacheEndpointProducerBuilder cacheConfiguration(
-                javax.cache.configuration.Configuration cacheConfiguration) {
-            doSetProperty("cacheConfiguration", cacheConfiguration);
-            return this;
-        }
-        /**
-         * A Configuration for the Cache.
-         * 
-         * The option will be converted to a
-         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
-         * type.
-         * 
-         * Group: common
-         * 
-         * @param cacheConfiguration the value to set
-         * @return the dsl builder
-         */
-        default JCacheEndpointProducerBuilder cacheConfiguration(
-                String cacheConfiguration) {
-            doSetProperty("cacheConfiguration", cacheConfiguration);
-            return this;
-        }
         /**
          * The Properties for the javax.cache.spi.CachingProvider to create the
          * CacheManager.
@@ -1061,6 +1027,40 @@ public interface JCacheEndpointBuilderFactory {
             doSetProperty("lazyStartProducer", lazyStartProducer);
             return this;
         }
+        /**
+         * A Configuration for the Cache.
+         * 
+         * The option is a:
+         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param cacheConfiguration the value to set
+         * @return the dsl builder
+         */
+        default AdvancedJCacheEndpointProducerBuilder cacheConfiguration(
+                javax.cache.configuration.Configuration cacheConfiguration) {
+            doSetProperty("cacheConfiguration", cacheConfiguration);
+            return this;
+        }
+        /**
+         * A Configuration for the Cache.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param cacheConfiguration the value to set
+         * @return the dsl builder
+         */
+        default AdvancedJCacheEndpointProducerBuilder cacheConfiguration(
+                String cacheConfiguration) {
+            doSetProperty("cacheConfiguration", cacheConfiguration);
+            return this;
+        }
         /**
          * The CacheLoader factory.
          * 
@@ -1239,40 +1239,6 @@ public interface JCacheEndpointBuilderFactory {
         default AdvancedJCacheEndpointBuilder advanced() {
             return (AdvancedJCacheEndpointBuilder) this;
         }
-        /**
-         * A Configuration for the Cache.
-         * 
-         * The option is a:
-         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
-         * type.
-         * 
-         * Group: common
-         * 
-         * @param cacheConfiguration the value to set
-         * @return the dsl builder
-         */
-        default JCacheEndpointBuilder cacheConfiguration(
-                javax.cache.configuration.Configuration cacheConfiguration) {
-            doSetProperty("cacheConfiguration", cacheConfiguration);
-            return this;
-        }
-        /**
-         * A Configuration for the Cache.
-         * 
-         * The option will be converted to a
-         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
-         * type.
-         * 
-         * Group: common
-         * 
-         * @param cacheConfiguration the value to set
-         * @return the dsl builder
-         */
-        default JCacheEndpointBuilder cacheConfiguration(
-                String cacheConfiguration) {
-            doSetProperty("cacheConfiguration", cacheConfiguration);
-            return this;
-        }
         /**
          * The Properties for the javax.cache.spi.CachingProvider to create the
          * CacheManager.
@@ -1504,6 +1470,40 @@ public interface JCacheEndpointBuilderFactory {
         default JCacheEndpointBuilder basic() {
             return (JCacheEndpointBuilder) this;
         }
+        /**
+         * A Configuration for the Cache.
+         * 
+         * The option is a:
+         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param cacheConfiguration the value to set
+         * @return the dsl builder
+         */
+        default AdvancedJCacheEndpointBuilder cacheConfiguration(
+                javax.cache.configuration.Configuration cacheConfiguration) {
+            doSetProperty("cacheConfiguration", cacheConfiguration);
+            return this;
+        }
+        /**
+         * A Configuration for the Cache.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;javax.cache.configuration.Configuration&lt;/code&gt;
+         * type.
+         * 
+         * Group: advanced
+         * 
+         * @param cacheConfiguration the value to set
+         * @return the dsl builder
+         */
+        default AdvancedJCacheEndpointBuilder cacheConfiguration(
+                String cacheConfiguration) {
+            doSetProperty("cacheConfiguration", cacheConfiguration);
+            return this;
+        }
         /**
          * The CacheLoader factory.
          * 
diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderClassResolver.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderClassResolver.java
index 330728cf27c..3a560dd558b 100644
--- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderClassResolver.java
+++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloaderClassResolver.java
@@ -21,12 +21,17 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
 import org.apache.camel.impl.engine.DefaultClassResolver;
 import org.apache.camel.tooling.maven.MavenGav;
+import org.apache.camel.tooling.model.PojoBeanModel;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
 
 public final class DependencyDownloaderClassResolver extends DefaultClassResolver {
 
+    private final CamelCatalog catalog = new DefaultCamelCatalog();
     private final List<ResourceResolverListener> resourceResolverListeners = new ArrayList<>();
     private final KnownDependenciesResolver knownDependenciesResolver;
     private final DependencyDownloader downloader;
@@ -56,6 +61,15 @@ public final class DependencyDownloaderClassResolver extends DefaultClassResolve
         if (answer == null) {
             // okay maybe the class is from a known GAV that we can download first and then load the class
             MavenGav gav = knownDependenciesResolver.mavenGavForClass(uri);
+            if (gav == null) {
+                // okay maybe its a known pojo-bean from the catalog
+                // lookup via class name without package
+                String last = StringHelper.afterLast(uri, ".", uri);
+                PojoBeanModel model = catalog.pojoBeanModel(last);
+                if (model != null && uri.equals(model.getJavaType())) {
+                    gav = MavenGav.fromCoordinates(model.getGroupId(), model.getArtifactId(), model.getVersion(), null, null);
+                }
+            }
             if (gav != null) {
                 if (!downloader.alreadyOnClasspath(gav.getGroupId(), gav.getArtifactId(),
                         gav.getVersion())) {
@@ -85,6 +99,15 @@ public final class DependencyDownloaderClassResolver extends DefaultClassResolve
         if (answer == null) {
             // okay maybe the class is from a known GAV that we can download first and then load the class
             MavenGav gav = knownDependenciesResolver.mavenGavForClass(name);
+            if (gav == null) {
+                // okay maybe its a known pojo-bean from the catalog
+                // lookup via class name without package
+                String last = StringHelper.afterLast(name, ".", name);
+                PojoBeanModel model = catalog.pojoBeanModel(last);
+                if (model != null && name.equals(model.getJavaType())) {
+                    gav = MavenGav.fromCoordinates(model.getGroupId(), model.getArtifactId(), model.getVersion(), null, null);
+                }
+            }
             if (gav != null) {
                 if (!downloader.alreadyOnClasspath(gav.getGroupId(), gav.getArtifactId(),
                         gav.getVersion())) {
diff --git a/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/JcacheUriDsl.kt b/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/JcacheUriDsl.kt
index 6f0f739a427..a9b4eb1cc24 100644
--- a/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/JcacheUriDsl.kt
+++ b/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/JcacheUriDsl.kt
@@ -50,13 +50,6 @@ public class JcacheUriDsl(
     it.url("$cacheName")
   }
 
-  /**
-   * A Configuration for the Cache
-   */
-  public fun cacheConfiguration(cacheConfiguration: String) {
-    it.property("cacheConfiguration", cacheConfiguration)
-  }
-
   /**
    * The Properties for the javax.cache.spi.CachingProvider to create the CacheManager
    */
@@ -270,6 +263,13 @@ public class JcacheUriDsl(
     it.property("lazyStartProducer", lazyStartProducer.toString())
   }
 
+  /**
+   * A Configuration for the Cache
+   */
+  public fun cacheConfiguration(cacheConfiguration: String) {
+    it.property("cacheConfiguration", cacheConfiguration)
+  }
+
   /**
    * The CacheLoader factory
    */
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 2cda577d491..352d25e82d1 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
@@ -71,6 +71,8 @@ public final class JsonMapper {
             return generateOtherModel(obj);
         } else if (obj.containsKey("model")) {
             return generateEipModel(obj);
+        } else if (obj.containsKey("bean")) {
+            return generatePojoBeanModel(obj);
         } else {
             return null;
         }
@@ -315,6 +317,27 @@ public final class JsonMapper {
         return model;
     }
 
+    public static PojoBeanModel generatePojoBeanModel(String json) {
+        JsonObject obj = deserialize(json);
+        return generatePojoBeanModel(obj);
+    }
+
+    public static PojoBeanModel generatePojoBeanModel(JsonObject obj) {
+        JsonObject mobj = (JsonObject) obj.get("bean");
+        PojoBeanModel model = new PojoBeanModel();
+        parseModel(mobj, model);
+        JsonObject mprp = (JsonObject) mobj.get("properties");
+        if (mprp != null) {
+            for (Map.Entry<String, Object> entry : mprp.entrySet()) {
+                JsonObject mp = (JsonObject) entry.getValue();
+                PojoBeanModel.PojoBeanOptionModel option = new PojoBeanModel.PojoBeanOptionModel();
+                parseOption(mp, option, entry.getKey());
+                model.addOption(option);
+            }
+        }
+        return model;
+    }
+
     public static String createParameterJsonSchema(EipModel model) {
         JsonObject wrapper = asJsonObject(model);
         return serialize(wrapper);
@@ -336,6 +359,22 @@ public final class JsonMapper {
         return wrapper;
     }
 
+    public static String createParameterJsonSchema(PojoBeanModel model) {
+        JsonObject wrapper = asJsonObject(model);
+        return serialize(wrapper);
+    }
+
+    public static JsonObject asJsonObject(PojoBeanModel model) {
+        JsonObject obj = new JsonObject();
+        baseToJson(model, obj);
+        artifactToJson(model, obj);
+        obj.entrySet().removeIf(e -> e.getValue() == null);
+        JsonObject wrapper = new JsonObject();
+        wrapper.put("model", obj);
+        wrapper.put("properties", asJsonObject(model.getOptions()));
+        return wrapper;
+    }
+
     public static LanguageModel generateLanguageModel(String json) {
         JsonObject obj = deserialize(json);
         return generateLanguageModel(obj);
diff --git a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/Kind.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/Kind.java
index f18e9d0df8c..a2a620873d8 100644
--- a/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/Kind.java
+++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/Kind.java
@@ -34,6 +34,7 @@ public enum Kind implements Jsonable {
     console,
     other,
     eip,
+    bean,
     model;
 
     @Override
@@ -51,4 +52,5 @@ public enum Kind implements Jsonable {
     public void toJson(final Writer writable) throws IOException {
         writable.write(Jsoner.serialize(name()));
     }
+
 }
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategy.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/PojoBeanModel.java
similarity index 58%
copy from core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategy.java
copy to tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/PojoBeanModel.java
index ac5175ed237..f5610f6d22f 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/aggregate/GroupedBodyAggregationStrategy.java
+++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/PojoBeanModel.java
@@ -14,23 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.processor.aggregate;
+package org.apache.camel.tooling.model;
 
+import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.camel.Exchange;
-import org.apache.camel.Message;
+public class PojoBeanModel extends ArtifactModel<PojoBeanModel.PojoBeanOptionModel> {
 
-/**
- * Aggregate body of input {@link Message} into a single combined Exchange holding all the aggregated bodies in a
- * {@link List} of type {@link Object} as the message body.
- *
- * This aggregation strategy can used in combination with {@link org.apache.camel.processor.Splitter} to batch messages
- */
-public class GroupedBodyAggregationStrategy extends AbstractListAggregationStrategy<Object> {
+    protected final List<PojoBeanModel.PojoBeanOptionModel> options = new ArrayList<>();
+
+    public PojoBeanModel() {
+    }
+
+    public void addOption(PojoBeanModel.PojoBeanOptionModel option) {
+        options.add(option);
+    }
 
     @Override
-    public Object getValue(Exchange exchange) {
-        return exchange.getIn().getBody();
+    public List<PojoBeanOptionModel> getOptions() {
+        return options;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.bean;
+    }
+
+    public static class PojoBeanOptionModel extends BaseOptionModel {
+
     }
 }
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGenerateConfigurerMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGenerateConfigurerMojo.java
index 96ba2caf708..e4c190a2fef 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGenerateConfigurerMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGenerateConfigurerMojo.java
@@ -145,9 +145,8 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
         Set<String> bootstrapSet = new LinkedHashSet<>();
         Set<String> bootstrapAndExtendedSet = new LinkedHashSet<>();
 
+        Index index = PackagePluginUtils.readJandexIndexIgnoreMissing(project, getLog());
         if (discoverClasses) {
-            Index index = PackagePluginUtils.readJandexIndexIgnoreMissing(project, getLog());
-
             if (index != null) {
                 // discover all classes annotated with @Configurer
                 List<AnnotationInstance> annotations = index.getAnnotations(CONFIGURER);
@@ -164,7 +163,9 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
 
         // additional classes
         if (classes != null && !classes.isEmpty()) {
-            Index index = readJandexIndex(project);
+            if (index == null) {
+                index = PackagePluginUtils.readJandexIndex(project);
+            }
             for (String clazz : classes) {
                 ClassInfo ci = index.getClassByName(DotName.createSimple(clazz));
                 AnnotationInstance ai = ci != null ? ci.declaredAnnotation(CONFIGURER) : null;
@@ -177,16 +178,16 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
         }
 
         for (String fqn : set) {
-            processClass(fqn, sourcesOutputDir, false, false, resourcesOutputDir);
+            processClass(index, fqn, sourcesOutputDir, false, false, resourcesOutputDir);
         }
         for (String fqn : bootstrapSet) {
-            processClass(fqn, sourcesOutputDir, false, true, resourcesOutputDir);
+            processClass(index, fqn, sourcesOutputDir, false, true, resourcesOutputDir);
         }
         for (String fqn : extendedSet) {
-            processClass(fqn, sourcesOutputDir, true, false, resourcesOutputDir);
+            processClass(index, fqn, sourcesOutputDir, true, false, resourcesOutputDir);
         }
         for (String fqn : bootstrapAndExtendedSet) {
-            processClass(fqn, sourcesOutputDir, true, true, resourcesOutputDir);
+            processClass(index, fqn, sourcesOutputDir, true, true, resourcesOutputDir);
         }
     }
 
@@ -206,7 +207,8 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
         }
     }
 
-    private void processClass(String fqn, File sourcesOutputDir, boolean extended, boolean bootstrap, File resourcesOutputDir)
+    private void processClass(
+            Index index, String fqn, File sourcesOutputDir, boolean extended, boolean bootstrap, File resourcesOutputDir)
             throws MojoExecutionException {
         try {
             String targetFqn = fqn;
@@ -215,7 +217,7 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
                 targetFqn = fqn.substring(pos + 1);
                 fqn = fqn.substring(0, pos);
             }
-            List<ConfigurerOption> options = processClass(fqn);
+            List<ConfigurerOption> options = processClass(index, fqn);
             generateConfigurer(fqn, targetFqn, options, sourcesOutputDir, extended, bootstrap);
             generateMetaInfConfigurer(fqn, targetFqn, resourcesOutputDir);
         } catch (Exception e) {
@@ -335,12 +337,15 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
         return artifacts;
     }
 
-    private List<ConfigurerOption> processClass(String fqn) throws ClassNotFoundException {
+    private List<ConfigurerOption> processClass(Index index, String fqn) throws ClassNotFoundException {
         List<ConfigurerOption> answer = new ArrayList<>();
         // filter out duplicates by using a names set that has already added
         Set<String> names = new HashSet<>();
 
         Class<?> clazz = projectClassLoader.loadClass(fqn);
+        ClassInfo ci = index != null ? index.getClassByName(DotName.createSimple(clazz)) : null;
+        boolean metadataOnly = ci != null && asBooleanDefaultFalse(ci.annotation(CONFIGURER), "metadataOnly");
+
         // find all public setters
         doWithMethods(clazz, m -> {
             boolean deprecated = m.isAnnotationPresent(Deprecated.class);
@@ -375,13 +380,19 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
                 String t = builder
                         ? Character.toUpperCase(m.getName().charAt(4)) + m.getName().substring(4 + 1)
                         : Character.toUpperCase(m.getName().charAt(3)) + m.getName().substring(3 + 1);
+                Field field = ReflectionHelper.findField(clazz, Character.toLowerCase(t.charAt(0)) + t.substring(1));
+                // check via the field whether to be included or not if we should only include fields marked up with @Metadata
+                if (metadataOnly && field != null) {
+                    if (!field.isAnnotationPresent(Metadata.class)) {
+                        return;
+                    }
+                }
                 if (names.add(t)) {
                     option = new ConfigurerOption(t, type, getter, builder);
                     answer.add(option);
                 } else {
                     boolean replace = false;
                     // try to find out what the real type is of the correspondent field so we chose among the clash
-                    Field field = ReflectionHelper.findField(clazz, Character.toLowerCase(t.charAt(0)) + t.substring(1));
                     if (field != null && field.getType().equals(type)) {
                         // this is the correct type for the new option
                         replace = true;
@@ -474,13 +485,19 @@ public abstract class AbstractGenerateConfigurerMojo extends AbstractGeneratorMo
     }
 
     private static boolean asBooleanDefaultTrue(AnnotationInstance ai, String name) {
-        AnnotationValue av = ai.value(name);
-        return av == null || av.asBoolean();
+        if (ai != null) {
+            AnnotationValue av = ai.value(name);
+            return av == null || av.asBoolean();
+        }
+        return true;
     }
 
     private static boolean asBooleanDefaultFalse(AnnotationInstance ai, String name) {
-        AnnotationValue av = ai.value(name);
-        return av != null && av.asBoolean();
+        if (ai != null) {
+            AnnotationValue av = ai.value(name);
+            return av != null && av.asBoolean();
+        }
+        return false;
     }
 
 }
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 6f5328c0929..a3a47d330b3 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
@@ -27,8 +27,6 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
-import java.net.URI;
-import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -36,7 +34,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -1077,7 +1074,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
                     option.setKind("property");
                     option.setName(name);
                     option.setDisplayName(displayName);
-                    option.setType(getType(fieldTypeName, false, isDuration));
+                    option.setType(MojoHelper.getType(fieldTypeName, false, isDuration));
                     option.setJavaType(fieldTypeName);
                     option.setRequired(required);
                     option.setDefaultValue(defaultValue);
@@ -1364,7 +1361,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         }
         option.setName(name);
         option.setDisplayName(displayName);
-        option.setType(getType(fieldTypeName, false, isDuration));
+        option.setType(MojoHelper.getType(fieldTypeName, false, isDuration));
         option.setJavaType(fieldTypeName);
         option.setRequired(required);
         option.setDefaultValue(defaultValue);
@@ -1553,7 +1550,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
             option.setName(name);
             option.setKind("path");
             option.setDisplayName(displayName);
-            option.setType(getType(fieldTypeName, false, isDuration));
+            option.setType(MojoHelper.getType(fieldTypeName, false, isDuration));
             option.setJavaType(fieldTypeName);
             option.setRequired(required);
             option.setDefaultValue(defaultValue);
@@ -1875,79 +1872,6 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         return fieldTypeName;
     }
 
-    /**
-     * Gets the JSON schema type.
-     *
-     * @param  type the java type
-     * @return      the json schema type, is never null, but returns <tt>object</tt> as the generic type
-     */
-    public static String getType(String type, boolean enumType, boolean isDuration) {
-        if (enumType) {
-            return "enum";
-        } else if (isDuration) {
-            return "duration";
-        } else if (type == null) {
-            // return generic type for unknown type
-            return "object";
-        } else if (type.equals(URI.class.getName()) || type.equals(URL.class.getName())) {
-            return "string";
-        } else if (type.equals(File.class.getName())) {
-            return "string";
-        } else if (type.equals(Date.class.getName())) {
-            return "string";
-        } else if (type.startsWith("java.lang.Class")) {
-            return "string";
-        } else if (type.startsWith("java.util.List") || type.startsWith("java.util.Collection")) {
-            return "array";
-        }
-
-        String primitive = getPrimitiveType(type);
-        if (primitive != null) {
-            return primitive;
-        }
-
-        return "object";
-    }
-
-    /**
-     * Gets the JSON schema primitive type.
-     *
-     * @param  name the java type
-     * @return      the json schema primitive type, or <tt>null</tt> if not a primitive
-     */
-    public static String getPrimitiveType(String name) {
-        // special for byte[] or Object[] as its common to use
-        if ("java.lang.byte[]".equals(name) || "byte[]".equals(name)) {
-            return "string";
-        } else if ("java.lang.Byte[]".equals(name) || "Byte[]".equals(name)) {
-            return "array";
-        } else if ("java.lang.Object[]".equals(name) || "Object[]".equals(name)) {
-            return "array";
-        } else if ("java.lang.String[]".equals(name) || "String[]".equals(name)) {
-            return "array";
-        } else if ("java.lang.Character".equals(name) || "Character".equals(name) || "char".equals(name)) {
-            return "string";
-        } else if ("java.lang.String".equals(name) || "String".equals(name)) {
-            return "string";
-        } else if ("java.lang.Boolean".equals(name) || "Boolean".equals(name) || "boolean".equals(name)) {
-            return "boolean";
-        } else if ("java.lang.Integer".equals(name) || "Integer".equals(name) || "int".equals(name)) {
-            return "integer";
-        } else if ("java.lang.Long".equals(name) || "Long".equals(name) || "long".equals(name)) {
-            return "integer";
-        } else if ("java.lang.Short".equals(name) || "Short".equals(name) || "short".equals(name)) {
-            return "integer";
-        } else if ("java.lang.Byte".equals(name) || "Byte".equals(name) || "byte".equals(name)) {
-            return "integer";
-        } else if ("java.lang.Float".equals(name) || "Float".equals(name) || "float".equals(name)) {
-            return "number";
-        } else if ("java.lang.Double".equals(name) || "Double".equals(name) || "double".equals(name)) {
-            return "number";
-        }
-
-        return null;
-    }
-
     /**
      * Gets the default value accordingly to its type
      *
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateComponentMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateComponentMojo.java
index 54e8563c891..d20cd9aaa7c 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateComponentMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateComponentMojo.java
@@ -50,6 +50,8 @@ public class GenerateComponentMojo extends AbstractGenerateMojo {
         invoke(GenerateInvokeOnHeaderMojo.class);
         // generate data-type-transformer
         invoke(GenerateDataTypeTransformerMojo.class);
+        // generate pojo-beans
+        invoke(GeneratePojoBeanMojo.class);
         // generate dev-console
         invoke(GenerateDevConsoleMojo.class);
         // prepare-components
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateMojo.java
index 982f872be20..84b7d2752d2 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GenerateMojo.java
@@ -52,6 +52,8 @@ public class GenerateMojo extends AbstractGenerateMojo {
         invoke(GenerateInvokeOnHeaderMojo.class);
         // generate data-type-transformer
         invoke(GenerateDataTypeTransformerMojo.class);
+        // generate pojo-beans
+        invoke(GeneratePojoBeanMojo.class);
         // generate dev-console
         invoke(GenerateDevConsoleMojo.class);
         // prepare-components
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java
new file mode 100644
index 00000000000..fb5594cf7ad
--- /dev/null
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java
@@ -0,0 +1,319 @@
+/*
+ * 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.lang.reflect.Field;
... 540 lines suppressed ...