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/14 18:49:00 UTC

(camel) branch pojo-beans created (now 79d5117eeac)

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

davsclaus pushed a change to branch pojo-beans
in repository https://gitbox.apache.org/repos/asf/camel.git


      at 79d5117eeac 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.

This branch includes the following new commits:

     new a0d5fa9fbd1 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.
     new cbae0027cb3 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.
     new 0fca0b6bce3 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.
     new fb1cee8406d 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.
     new 09d6078875b 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.
     new 4506f0d543a 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.
     new 9f8ce52c101 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.
     new 260468a9922 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.
     new 1ee83e533cf 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.
     new 79d5117eeac 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.

The 10 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(camel) 07/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9f8ce52c101b39e6571bea77f62fcb35671bccee
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 17:38:29 2024 +0100

    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.
---
 .../META-INF/services/org/apache/camel/bean.properties   |  7 +++++++
 .../org/apache/camel/bean/FileIdempotentRepository.json  | 16 ++++++++++++++++
 .../apache/camel/bean/MemoryIdempotentRepository.json    | 16 ++++++++++++++++
 .../processor/idempotent/FileIdempotentRepository.java   | 10 ++++++++--
 .../processor/idempotent/MemoryIdempotentRepository.java |  5 +++++
 5 files changed, 52 insertions(+), 2 deletions(-)

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..5a5da2cace5
--- /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=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/FileIdempotentRepository.json b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/FileIdempotentRepository.json
new file mode 100644
index 00000000000..48cdb0868ab
--- /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",
+    "options": { "dropOldestFileStore": { "index": 0, "kind": "property", "displayName": "Drop Oldest File Store", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "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." }, "fileStore": { "index": 1, "kind": "property", "displayName": "File St [...]
+  }
+}
+
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..84aac9a7c66
--- /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",
+    "options": { "cacheSize": { "index": 0, "kind": "property", "displayName": "Cache Size", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "description": "Maximum elements that can be stored in-memory" } }
+  }
+}
+
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..c1f4b296ee7 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
@@ -29,6 +29,7 @@ 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.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 +51,23 @@ 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.")
 @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..22a0d14506e 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
@@ -22,6 +22,7 @@ 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.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 +32,13 @@ 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.")
 @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() {


(camel) 05/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 09d6078875b820361a1505cb0a943cb02c535b92
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 16:31:23 2024 +0100

    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.
---
 .../META-INF/services/org/apache/camel/bean.properties    |  2 +-
 .../apache/camel/bean/GroupedBodyAggregationStrategy.json | 15 +++++++++++++++
 .../camel/bean/GroupedExchangeAggregationStrategy.json    | 15 +++++++++++++++
 .../aggregate/GroupedBodyAggregationStrategy.java         |  5 +++++
 .../aggregate/GroupedExchangeAggregationStrategy.java     |  5 +++++
 5 files changed, 41 insertions(+), 1 deletion(-)

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
index 88fd1692084..80e93133b3c 100644
--- 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
@@ -1,5 +1,5 @@
 # Generated by camel build tools - do NOT edit this file!
-bean=GroupedMessageAggregationStrategy StringAggregationStrategy UseLatestAggregationStrategy UseOriginalAggregationStrategy
+bean=GroupedBodyAggregationStrategy GroupedExchangeAggregationStrategy GroupedMessageAggregationStrategy StringAggregationStrategy UseLatestAggregationStrategy UseOriginalAggregationStrategy
 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/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/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..d93e8f9bb04 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,7 @@ import java.util.List;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+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 +28,10 @@ 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.")
 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..7a3c0c97f3a 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,7 @@ package org.apache.camel.processor.aggregate;
 import java.util.List;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.DefaultExchange;
 
 /**
@@ -28,6 +29,10 @@ 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.")
 public class GroupedExchangeAggregationStrategy extends AbstractListAggregationStrategy<Exchange> {
 
     @Override


(camel) 08/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 260468a9922e58fa080fa1bcd9f99e0bd6bba3cc
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 18:11:54 2024 +0100

    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.
---
 .../services/org/apache/camel/bean.properties      |  2 +-
 .../camel/bean/DefaultHeaderFilterStrategy.json    | 16 +++++++++
 .../camel/bean/FileIdempotentRepository.json       |  2 +-
 .../camel/bean/MemoryIdempotentRepository.json     |  2 +-
 .../camel/support/DefaultHeaderFilterStrategy.java | 41 +++++++++++++++++++---
 .../idempotent/FileIdempotentRepository.java       |  8 +++--
 .../idempotent/MemoryIdempotentRepository.java     |  2 +-
 .../maven/packaging/GeneratePojoBeanMojo.java      |  8 +++--
 8 files changed, 68 insertions(+), 13 deletions(-)

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
index 5a5da2cace5..25ce5d4b2f9 100644
--- 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
@@ -1,5 +1,5 @@
 # Generated by camel build tools - do NOT edit this file!
-bean=FileIdempotentRepository MemoryIdempotentRepository
+bean=DefaultHeaderFilterStrategy FileIdempotentRepository MemoryIdempotentRepository
 groupId=org.apache.camel
 artifactId=camel-support
 version=4.5.0-SNAPSHOT
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..8d359b034cd
--- /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",
+    "options": { "allowNullValues": { "index": 0, "kind": "property", "displayName": "Allow Null Values", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.support.DefaultHeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "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." }, "caseInsensitive": { "index [...]
+  }
+}
+
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
index 48cdb0868ab..e40fb4b2bee 100644
--- 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
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "dropOldestFileStore": { "index": 0, "kind": "property", "displayName": "Drop Oldest File Store", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "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." }, "fileStore": { "index": 1, "kind": "property", "displayName": "File St [...]
+    "options": { "dropOldestFileStore": { "index": 0, "kind": "property", "displayName": "Drop Oldest File Store", "required": false, "type": "object", "javaType": "org.apache.camel.support.processor.idempotent.FileIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "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." }, "file [...]
   }
 }
 
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
index 84aac9a7c66..4c152136b51 100644
--- 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
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "cacheSize": { "index": 0, "kind": "property", "displayName": "Cache Size", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "description": "Maximum elements that can be stored in-memory" } }
+    "options": { "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/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultHeaderFilterStrategy.java
index 7a99e29ab16..901af91262f 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
@@ -23,17 +23,20 @@ import java.util.regex.Pattern;
 
 import org.apache.camel.Exchange;
 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.")
 public class DefaultHeaderFilterStrategy implements HeaderFilterStrategy {
 
     /**
@@ -49,17 +52,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 +117,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 +193,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 +288,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 +302,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 c1f4b296ee7..7770ba84ba9 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
@@ -52,7 +52,7 @@ import org.slf4j.LoggerFactory;
  * file store and make room for newer entries.
  */
 @Metadata(label = "bean",
-        description = "A file based IdempotentRepository.")
+          description = "A file based IdempotentRepository.")
 @ManagedResource(description = "File based idempotent repository")
 public class FileIdempotentRepository extends ServiceSupport implements IdempotentRepository {
 
@@ -64,10 +64,12 @@ public class FileIdempotentRepository extends ServiceSupport implements Idempote
 
     @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)
+    @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")
+                            + " 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 22a0d14506e..898489d9bde 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
@@ -33,7 +33,7 @@ import org.apache.camel.support.service.ServiceSupport;
  * 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.")
+          description = "A memory based IdempotentRepository.")
 @ManagedResource(description = "Memory based idempotent repository")
 public class MemoryIdempotentRepository extends ServiceSupport implements IdempotentRepository {
     private Map<String, Object> cache;
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
index 4787b307841..f9d3e0f6400 100644
--- 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
@@ -191,8 +191,12 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
                         }
                         o.setDisplayName(displayName);
                         o.setDeprecated(fi.hasAnnotation(Deprecated.class));
-                        o.setJavaType(fi.type().name().toString());
-                        o.setType(getType(o.getJavaType(), false, false));
+                        String javaType = annotationValue(ai, "javaType");
+                        if (javaType == null) {
+                            javaType = ci.name().toString();
+                        }
+                        o.setJavaType(javaType);
+                        o.setType(getType(javaType, false, false));
                         o.setDescription(annotationValue(ai, "description"));
                         String enums = annotationValue(ai, "enums");
                         if (enums != null) {


(camel) 02/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit cbae0027cb3630dbe4e84f220f7758062134e67a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 15:37:05 2024 +0100

    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.
---
 .../camel/bean/UseLatestAggregationStrategy.json   | 15 +++++++++++
 .../services/org/apache/camel/beans.properties     |  7 +++++
 .../aggregate/UseLatestAggregationStrategy.java    | 12 ++++-----
 .../maven/packaging/GeneratePojoBeanMojo.java      | 30 ++++++++++++++--------
 4 files changed, 47 insertions(+), 17 deletions(-)

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/beans.properties b/core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/beans.properties
new file mode 100644
index 00000000000..a4277ba5e66
--- /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=org.apache.camel.processor.aggregate.UseLatestAggregationStrategy
+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/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 eb48f844d81..0b94b2b7441 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
@@ -26,10 +26,10 @@ import org.apache.camel.spi.Metadata;
  * 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.")
+@Metadata(label = "bean", title = "Use Latest",
+          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.")
 public class UseLatestAggregationStrategy implements AggregationStrategy {
 
     @Override
@@ -77,8 +77,8 @@ public class UseLatestAggregationStrategy implements AggregationStrategy {
 
         // propagate exception from old exchange if there isn't already an exception
         if (oldExchange.isFailed() || oldExchange.isRollbackOnly() || oldExchange.isRollbackOnlyLast()
-            || oldExchange.getExchangeExtension().isErrorHandlerHandledSet()
-               && oldExchange.getExchangeExtension().isErrorHandlerHandled()) {
+                || oldExchange.getExchangeExtension().isErrorHandlerHandledSet()
+                        && oldExchange.getExchangeExtension().isErrorHandlerHandled()) {
             // propagate failure by using old exchange as the answer
             return oldExchange;
         }
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
index 31fc4fc4ca3..879fe0df8a7 100644
--- 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
@@ -61,6 +61,7 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
 
     private static class BeanPojoModel {
         private String name;
+        private String title;
         private String className;
         private String interfaceName;
         private String description;
@@ -74,6 +75,14 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
             this.name = name;
         }
 
+        public String getTitle() {
+            return title;
+        }
+
+        public void setTitle(String title) {
+            this.title = title;
+        }
+
         public String getClassName() {
             return className;
         }
@@ -134,10 +143,15 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
             String label = annotationValue(a, "label");
             if ("bean".equals(label)) {
                 BeanPojoModel model = new BeanPojoModel();
-                String currentClass = a.target().asClass().name().toString();
-                boolean deprecated = a.target().asClass().hasAnnotation(Deprecated.class);
                 model.setName(a.target().asClass().simpleName());
-                model.setClassName(currentClass);
+                boolean deprecated = a.target().asClass().hasAnnotation(Deprecated.class);
+                String title = annotationValue(a, "title");
+                if (title == null) {
+                    title = Strings.camelCaseToDash(model.getName());
+                    title = Strings.camelDashToTitle(title);
+                }
+                model.setTitle(title);
+                model.setClassName(a.target().asClass().name().toString());
                 model.setDeprecated(deprecated);
                 model.setDescription(annotationValue(a, "description"));
                 for (DotName dn : a.target().asClass().interfaceNames()) {
@@ -191,7 +205,7 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
         if (model.getInterfaceName() != null) {
             jo.put("interfaceType", model.getInterfaceName());
         }
-        jo.put("title", asTitle(model.getClassName()));
+        jo.put("title", asTitle(model.getName()));
         if (model.getDescription() != null) {
             jo.put("description", model.getDescription());
         }
@@ -209,13 +223,7 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
     }
 
     private String asTitle(String name) {
-        name = Strings.camelDashToTitle(name);
-        String part = Strings.after(name, ":");
-        if (part != null) {
-            part = Strings.capitalize(part);
-            name = Strings.before(name, ":") + " (" + part + ")";
-        }
-        return name;
+        return Strings.asTitle(name);
     }
 
 }


(camel) 06/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4506f0d543a0806b54071fe3f29620a90e30fb69
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 17:24:54 2024 +0100

    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.
---
 .../META-INF/services/org/apache/camel/bean.properties   |  2 +-
 .../apache/camel/bean/MemoryAggregationRepository.json   | 16 ++++++++++++++++
 .../processor/aggregate/MemoryAggregationRepository.java | 15 ++++++++++++++-
 3 files changed, 31 insertions(+), 2 deletions(-)

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
index 80e93133b3c..08e572c6577 100644
--- 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
@@ -1,5 +1,5 @@
 # Generated by camel build tools - do NOT edit this file!
-bean=GroupedBodyAggregationStrategy GroupedExchangeAggregationStrategy GroupedMessageAggregationStrategy StringAggregationStrategy UseLatestAggregationStrategy UseOriginalAggregationStrategy
+bean=GroupedBodyAggregationStrategy GroupedExchangeAggregationStrategy GroupedMessageAggregationStrategy MemoryAggregationRepository StringAggregationStrategy UseLatestAggregationStrategy UseOriginalAggregationStrategy
 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..4e2092ec9fc
--- /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.spi.OptimisticLockingAggregationRepository",
+    "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",
+    "options": { "optimisticLocking": { "index": 0, "kind": "property", "displayName": "Optimistic Locking", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "description": "Whether to use optimistic locking" } }
+  }
+}
+
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..3e49428fd0a 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,7 @@ import java.util.concurrent.ConcurrentMap;
 
 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.support.service.ServiceSupport;
 
@@ -31,9 +32,13 @@ 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.")
 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 +48,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) {


(camel) 01/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit a0d5fa9fbd1355aa0e95ff144d536f29b91d3b4d
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 15:23:17 2024 +0100

    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.
---
 .../aggregate/UseLatestAggregationStrategy.java    |   9 +-
 .../maven/packaging/GenerateComponentMojo.java     |   2 +
 .../apache/camel/maven/packaging/GenerateMojo.java |   2 +
 .../maven/packaging/GeneratePojoBeanMojo.java      | 221 +++++++++++++++++++++
 4 files changed, 232 insertions(+), 2 deletions(-)

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..eb48f844d81 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,17 @@ 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.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.")
 public class UseLatestAggregationStrategy implements AggregationStrategy {
 
     @Override
@@ -72,8 +77,8 @@ public class UseLatestAggregationStrategy implements AggregationStrategy {
 
         // propagate exception from old exchange if there isn't already an exception
         if (oldExchange.isFailed() || oldExchange.isRollbackOnly() || oldExchange.isRollbackOnlyLast()
-                || oldExchange.getExchangeExtension().isErrorHandlerHandledSet()
-                        && oldExchange.getExchangeExtension().isErrorHandlerHandled()) {
+            || oldExchange.getExchangeExtension().isErrorHandlerHandledSet()
+               && oldExchange.getExchangeExtension().isErrorHandlerHandled()) {
             // propagate failure by using old exchange as the answer
             return oldExchange;
         }
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..31fc4fc4ca3
--- /dev/null
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java
@@ -0,0 +1,221 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.StringJoiner;
+
+import org.apache.camel.maven.packaging.generics.PackagePluginUtils;
+import org.apache.camel.tooling.util.PackageHelper;
+import org.apache.camel.tooling.util.Strings;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.jboss.jandex.AnnotationInstance;
+import org.jboss.jandex.DotName;
+import org.jboss.jandex.Index;
+
+import static org.apache.camel.maven.packaging.MojoHelper.annotationValue;
+
+/**
+ * Factory for generating code for Camel pojo beans that are intended for end user to use with Camel EIPs and
+ * components.
+ */
+@Mojo(name = "generate-pojo-bean", threadSafe = true, defaultPhase = LifecyclePhase.PROCESS_CLASSES,
+      requiresDependencyCollection = ResolutionScope.COMPILE,
+      requiresDependencyResolution = ResolutionScope.COMPILE)
+public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
+
+    public static final DotName METADATA = DotName.createSimple("org.apache.camel.spi.Metadata");
+
+    /**
+     * The project build directory
+     */
+    @Parameter(defaultValue = "${project.build.directory}")
+    protected File buildDir;
+
+    @Parameter(defaultValue = "${project.basedir}/src/generated/resources")
+    protected File resourcesOutputDir;
+
+    private static class BeanPojoModel {
+        private String name;
+        private String className;
+        private String interfaceName;
+        private String description;
+        private boolean deprecated;
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public String getClassName() {
+            return className;
+        }
+
+        public void setClassName(String className) {
+            this.className = className;
+        }
+
+        public String getInterfaceName() {
+            return interfaceName;
+        }
+
+        public void setInterfaceName(String interfaceName) {
+            this.interfaceName = interfaceName;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public void setDescription(String description) {
+            this.description = description;
+        }
+
+        public boolean isDeprecated() {
+            return deprecated;
+        }
+
+        public void setDeprecated(boolean deprecated) {
+            this.deprecated = deprecated;
+        }
+    }
+
+    public GeneratePojoBeanMojo() {
+    }
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if ("pom".equals(project.getPackaging())) {
+            return;
+        }
+
+        buildDir = new File(project.getBuild().getDirectory());
+
+        if (resourcesOutputDir == null) {
+            resourcesOutputDir = new File(project.getBasedir(), "src/generated/resources");
+        }
+
+        Index index = PackagePluginUtils.readJandexIndexIgnoreMissing(project, getLog());
+        if (index == null) {
+            return;
+        }
+
+        List<BeanPojoModel> models = new ArrayList<>();
+        List<AnnotationInstance> annotations = index.getAnnotations(METADATA);
+        annotations.forEach(a -> {
+            // only @Metadata(label="bean") is selected
+            String label = annotationValue(a, "label");
+            if ("bean".equals(label)) {
+                BeanPojoModel model = new BeanPojoModel();
+                String currentClass = a.target().asClass().name().toString();
+                boolean deprecated = a.target().asClass().hasAnnotation(Deprecated.class);
+                model.setName(a.target().asClass().simpleName());
+                model.setClassName(currentClass);
+                model.setDeprecated(deprecated);
+                model.setDescription(annotationValue(a, "description"));
+                for (DotName dn : a.target().asClass().interfaceNames()) {
+                    if (dn.packagePrefix().startsWith("org.apache.camel")) {
+                        model.setInterfaceName(dn.toString());
+                        break;
+                    }
+                }
+                // TODO: getter/setter for options ala EIP/components
+                models.add(model);
+            }
+        });
+        models.sort(Comparator.comparing(BeanPojoModel::getClassName));
+
+        if (!models.isEmpty()) {
+            try {
+                StringJoiner names = new StringJoiner(" ");
+                for (var model : models) {
+                    names.add(model.getClassName());
+                    JsonObject jo = asJsonObject(model);
+                    String json = jo.toJson();
+                    json = Jsoner.prettyPrint(json, 2);
+                    String fn = sanitizeFileName(model.getName()) + PackageHelper.JSON_SUFIX;
+                    boolean updated = updateResource(resourcesOutputDir.toPath(),
+                            "META-INF/services/org/apache/camel/bean/" + fn,
+                            json + NL);
+                    if (updated) {
+                        getLog().info("Updated bean json: " + model.getName());
+                    }
+                }
+
+                // generate marker file
+                File camelMetaDir = new File(resourcesOutputDir, "META-INF/services/org/apache/camel/");
+                int count = models.size();
+                String properties = createProperties(project, "beans", names.toString());
+                updateResource(camelMetaDir.toPath(), "beans.properties", properties);
+                getLog().info("Generated beans.properties containing " + count + " Camel "
+                              + (count > 1 ? "beans: " : "bean: ") + names);
+            } catch (Exception e) {
+                throw new MojoExecutionException(e);
+            }
+        }
+    }
+
+    private JsonObject asJsonObject(BeanPojoModel model) {
+        JsonObject jo = new JsonObject();
+        // we need to know the maven GAV also
+        jo.put("kind", "bean");
+        jo.put("name", model.getName());
+        jo.put("javaType", model.getClassName());
+        if (model.getInterfaceName() != null) {
+            jo.put("interfaceType", model.getInterfaceName());
+        }
+        jo.put("title", asTitle(model.getClassName()));
+        if (model.getDescription() != null) {
+            jo.put("description", model.getDescription());
+        }
+        jo.put("deprecated", model.isDeprecated());
+        jo.put("groupId", project.getGroupId());
+        jo.put("artifactId", project.getArtifactId());
+        jo.put("version", project.getVersion());
+        JsonObject root = new JsonObject();
+        root.put("bean", jo);
+        return root;
+    }
+
+    private String sanitizeFileName(String fileName) {
+        return fileName.replaceAll("[^A-Za-z0-9+-/]", "-");
+    }
+
+    private String asTitle(String name) {
+        name = Strings.camelDashToTitle(name);
+        String part = Strings.after(name, ":");
+        if (part != null) {
+            part = Strings.capitalize(part);
+            name = Strings.before(name, ":") + " (" + part + ")";
+        }
+        return name;
+    }
+
+}


(camel) 04/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit fb1cee8406d4cb621e37782b3d51e1e1001772d2
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 16:27:10 2024 +0100

    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.
---
 .../services/org/apache/camel/bean.properties      |  2 +-
 .../bean/GroupedMessageAggregationStrategy.json    | 15 ++++
 .../camel/bean/StringAggregationStrategy.json      | 16 ++++
 .../GroupedMessageAggregationStrategy.java         |  5 ++
 .../aggregate/StringAggregationStrategy.java       | 21 ++++++
 .../packaging/EndpointSchemaGeneratorMojo.java     | 82 +--------------------
 .../maven/packaging/GeneratePojoBeanMojo.java      | 85 +++++++++++++++++++---
 .../apache/camel/maven/packaging/MojoHelper.java   | 76 +++++++++++++++++++
 8 files changed, 210 insertions(+), 92 deletions(-)

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
index 348c3b28c96..88fd1692084 100644
--- 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
@@ -1,5 +1,5 @@
 # Generated by camel build tools - do NOT edit this file!
-bean=UseLatestAggregationStrategy UseOriginalAggregationStrategy
+bean=GroupedMessageAggregationStrategy StringAggregationStrategy UseLatestAggregationStrategy UseOriginalAggregationStrategy
 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/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..1702da816d7
--- /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",
+    "options": { "delimiter": { "index": 0, "kind": "property", "displayName": "Delimiter", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Delimiter used for joining strings together." } }
+  }
+}
+
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..aca104407c3 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,7 @@ import java.util.List;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.DefaultExchange;
 
 /**
@@ -29,6 +30,10 @@ 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.")
 public class GroupedMessageAggregationStrategy extends AbstractListAggregationStrategy<Message> {
 
     @Override
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..5e8694fd923 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,7 @@ 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.Metadata;
 import org.apache.camel.support.builder.ExpressionBuilder;
 
 /**
@@ -28,11 +29,31 @@ 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")
 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/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/GeneratePojoBeanMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/GeneratePojoBeanMojo.java
index 438b0de9744..4787b307841 100644
--- 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
@@ -21,12 +21,14 @@ import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.StringJoiner;
+import java.util.stream.Stream;
 
 import org.apache.camel.maven.packaging.generics.PackagePluginUtils;
+import org.apache.camel.tooling.model.BaseOptionModel;
+import org.apache.camel.tooling.model.JsonMapper;
 import org.apache.camel.tooling.util.PackageHelper;
 import org.apache.camel.tooling.util.Strings;
 import org.apache.camel.util.json.JsonObject;
-import org.apache.camel.util.json.Jsoner;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugins.annotations.LifecyclePhase;
@@ -34,10 +36,13 @@ import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.jboss.jandex.AnnotationInstance;
+import org.jboss.jandex.ClassInfo;
 import org.jboss.jandex.DotName;
+import org.jboss.jandex.FieldInfo;
 import org.jboss.jandex.Index;
 
 import static org.apache.camel.maven.packaging.MojoHelper.annotationValue;
+import static org.apache.camel.maven.packaging.MojoHelper.getType;
 
 /**
  * Factory for generating code for Camel pojo beans that are intended for end user to use with Camel EIPs and
@@ -66,6 +71,7 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
         private String interfaceName;
         private String description;
         private boolean deprecated;
+        private final List<BeanPojoOptionModel> options = new ArrayList<>();
 
         public String getName() {
             return name;
@@ -114,6 +120,18 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
         public void setDeprecated(boolean deprecated) {
             this.deprecated = deprecated;
         }
+
+        public void addOption(BeanPojoOptionModel option) {
+            this.options.add(option);
+        }
+
+        public List<BeanPojoOptionModel> getOptions() {
+            return options;
+        }
+    }
+
+    private static class BeanPojoOptionModel extends BaseOptionModel {
+
     }
 
     public GeneratePojoBeanMojo() {
@@ -143,25 +161,47 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
             String label = annotationValue(a, "label");
             if ("bean".equals(label)) {
                 BeanPojoModel model = new BeanPojoModel();
-                model.setName(a.target().asClass().simpleName());
-                boolean deprecated = a.target().asClass().hasAnnotation(Deprecated.class);
+                ClassInfo ci = a.target().asClass();
+                model.setName(ci.simpleName());
+                boolean deprecated = ci.hasAnnotation(Deprecated.class);
                 String title = annotationValue(a, "title");
                 if (title == null) {
                     title = Strings.camelCaseToDash(model.getName());
                     title = Strings.camelDashToTitle(title);
                 }
                 model.setTitle(title);
-                model.setClassName(a.target().asClass().name().toString());
+                model.setClassName(ci.name().toString());
                 model.setDeprecated(deprecated);
                 model.setDescription(annotationValue(a, "description"));
-                for (DotName dn : a.target().asClass().interfaceNames()) {
-                    if (dn.packagePrefix().startsWith("org.apache.camel")) {
-                        model.setInterfaceName(dn.toString());
-                        break;
+                model.setInterfaceName(interfaceName(index, ci));
+
+                // find all fields with @Metadata as options
+                for (FieldInfo fi : ci.fields()) {
+                    AnnotationInstance ai = fi.annotation(METADATA);
+                    if (ai != null) {
+                        BeanPojoOptionModel o = new BeanPojoOptionModel();
+                        o.setKind("property");
+                        o.setName(fi.name());
+                        o.setLabel(annotationValue(ai, "label"));
+                        o.setDefaultValue(annotationValue(ai, "defaultValue"));
+                        o.setRequired("true".equals(annotationValue(ai, "required")));
+                        String displayName = annotationValue(ai, "title");
+                        if (displayName == null) {
+                            displayName = Strings.asTitle(o.getName());
+                        }
+                        o.setDisplayName(displayName);
+                        o.setDeprecated(fi.hasAnnotation(Deprecated.class));
+                        o.setJavaType(fi.type().name().toString());
+                        o.setType(getType(o.getJavaType(), false, false));
+                        o.setDescription(annotationValue(ai, "description"));
+                        String enums = annotationValue(ai, "enums");
+                        if (enums != null) {
+                            String[] values = enums.split(",");
+                            o.setEnums(Stream.of(values).map(String::trim).toList());
+                        }
+                        model.addOption(o);
                     }
                 }
-
-                // TODO: getter/setter for options ala EIP/components
                 models.add(model);
             }
         });
@@ -173,8 +213,7 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
                 for (var model : models) {
                     names.add(model.getName());
                     JsonObject jo = asJsonObject(model);
-                    String json = jo.toJson();
-                    json = Jsoner.prettyPrint(json, 2);
+                    String json = JsonMapper.serialize(jo);
                     String fn = sanitizeFileName(model.getName()) + PackageHelper.JSON_SUFIX;
                     boolean updated = updateResource(resourcesOutputDir.toPath(),
                             "META-INF/services/org/apache/camel/bean/" + fn,
@@ -197,6 +236,22 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
         }
     }
 
+    private static String interfaceName(Index index, ClassInfo target) {
+        for (DotName dn : target.interfaceNames()) {
+            if (dn.packagePrefix().startsWith("org.apache.camel")) {
+                return dn.toString();
+            }
+        }
+        if (target.superName() != null) {
+            DotName dn = target.superName();
+            ClassInfo ci = index.getClassByName(dn);
+            if (ci != null) {
+                return interfaceName(index, ci);
+            }
+        }
+        return null;
+    }
+
     private JsonObject asJsonObject(BeanPojoModel model) {
         JsonObject jo = new JsonObject();
         // we need to know the maven GAV also
@@ -214,6 +269,12 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
         jo.put("groupId", project.getGroupId());
         jo.put("artifactId", project.getArtifactId());
         jo.put("version", project.getVersion());
+
+        if (!model.getOptions().isEmpty()) {
+            JsonObject options = JsonMapper.asJsonObject(model.getOptions());
+            jo.put("options", options);
+        }
+
         JsonObject root = new JsonObject();
         root.put("bean", jo);
         return root;
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MojoHelper.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MojoHelper.java
index 350579b5fc6..95f5a1de142 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MojoHelper.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/MojoHelper.java
@@ -16,9 +16,13 @@
  */
 package org.apache.camel.maven.packaging;
 
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
 import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 import org.jboss.jandex.AnnotationInstance;
@@ -132,4 +136,76 @@ public final class MojoHelper {
         return s == null || s.isBlank() ? null : s;
     }
 
+    /**
+     * 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;
+    }
 }


(camel) 09/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1ee83e533cfca1adcaaf2ba2b8e2effe0e5833f7
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 18:48:09 2024 +0100

    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      | 10 ++++
 .../catalog/beans/DefaultHeaderFilterStrategy.json | 16 +++++
 .../catalog/beans/FileIdempotentRepository.json    | 16 +++++
 .../beans/GroupedBodyAggregationStrategy.json      | 15 +++++
 .../beans/GroupedExchangeAggregationStrategy.json  | 15 +++++
 .../beans/GroupedMessageAggregationStrategy.json   | 15 +++++
 .../catalog/beans/MemoryAggregationRepository.json | 16 +++++
 .../catalog/beans}/MemoryIdempotentRepository.json |  2 +-
 .../catalog/beans/StringAggregationStrategy.json   | 16 +++++
 .../beans/UseLatestAggregationStrategy.json        | 15 +++++
 .../beans/UseOriginalAggregationStrategy.json      | 15 +++++
 .../catalog/components/langchain-embeddings.json   |  4 +-
 .../camel/bean/DefaultHeaderFilterStrategy.json    |  2 +-
 .../camel/bean/FileIdempotentRepository.json       |  2 +-
 .../camel/bean/MemoryIdempotentRepository.json     |  2 +-
 .../org/apache/camel/tooling/model/JsonMapper.java | 38 ++++++++++++
 .../apache/camel/tooling/model/PojoBeanModel.java  | 46 +++++++++++++++
 .../maven/packaging/GeneratePojoBeanMojo.java      |  2 +-
 .../camel/maven/packaging/PrepareCatalogMojo.java  | 69 +++++++++++++++++++++-
 19 files changed, 308 insertions(+), 8 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..682e217224d
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans.properties
@@ -0,0 +1,10 @@
+DefaultHeaderFilterStrategy
+FileIdempotentRepository
+GroupedBodyAggregationStrategy
+GroupedExchangeAggregationStrategy
+GroupedMessageAggregationStrategy
+MemoryAggregationRepository
+MemoryIdempotentRepository
+StringAggregationStrategy
+UseLatestAggregationStrategy
+UseOriginalAggregationStrategy
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..bfe3e06376a
--- /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": { "allowNullValues": { "index": 0, "kind": "property", "displayName": "Allow Null Values", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.support.DefaultHeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "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." }, "caseInsensitive": { "in [...]
+  }
+}
+
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..ca6dbee7ea3
--- /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": { "dropOldestFileStore": { "index": 0, "kind": "property", "displayName": "Drop Oldest File Store", "required": false, "type": "object", "javaType": "org.apache.camel.support.processor.idempotent.FileIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "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." }, "f [...]
+  }
+}
+
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/MemoryAggregationRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryAggregationRepository.json
new file mode 100644
index 00000000000..4e2092ec9fc
--- /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.spi.OptimisticLockingAggregationRepository",
+    "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",
+    "options": { "optimisticLocking": { "index": 0, "kind": "property", "displayName": "Optimistic Locking", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "description": "Whether to use optimistic locking" } }
+  }
+}
+
diff --git a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json
similarity index 56%
copy from core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
copy to catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json
index 4c152136b51..a70bbdcdf2e 100644
--- a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/bean/MemoryIdempotentRepository.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/MemoryIdempotentRepository.json
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "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" } }
+    "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/StringAggregationStrategy.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/beans/StringAggregationStrategy.json
new file mode 100644
index 00000000000..1702da816d7
--- /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",
+    "options": { "delimiter": { "index": 0, "kind": "property", "displayName": "Delimiter", "required": false, "type": "string", "javaType": "java.lang.String", "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/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/components/langchain-embeddings.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain-embeddings.json
index a064e3985a3..00a08f7f076 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain-embeddings.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/langchain-embeddings.json
@@ -3,7 +3,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",
@@ -11,7 +11,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/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
index 8d359b034cd..bfe3e06376a 100644
--- 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
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "allowNullValues": { "index": 0, "kind": "property", "displayName": "Allow Null Values", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.support.DefaultHeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "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." }, "caseInsensitive": { "index [...]
+    "properties": { "allowNullValues": { "index": 0, "kind": "property", "displayName": "Allow Null Values", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.support.DefaultHeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "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." }, "caseInsensitive": { "in [...]
   }
 }
 
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
index e40fb4b2bee..ca6dbee7ea3 100644
--- 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
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "dropOldestFileStore": { "index": 0, "kind": "property", "displayName": "Drop Oldest File Store", "required": false, "type": "object", "javaType": "org.apache.camel.support.processor.idempotent.FileIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "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." }, "file [...]
+    "properties": { "dropOldestFileStore": { "index": 0, "kind": "property", "displayName": "Drop Oldest File Store", "required": false, "type": "object", "javaType": "org.apache.camel.support.processor.idempotent.FileIdempotentRepository", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "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." }, "f [...]
   }
 }
 
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
index 4c152136b51..a70bbdcdf2e 100644
--- 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
@@ -10,7 +10,7 @@
     "groupId": "org.apache.camel",
     "artifactId": "camel-support",
     "version": "4.5.0-SNAPSHOT",
-    "options": { "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" } }
+    "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/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..8b5302d5011 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) obj.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,21 @@ 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);
+        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/PojoBeanModel.java b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/PojoBeanModel.java
new file mode 100644
index 00000000000..fccb953d2f8
--- /dev/null
+++ b/tooling/camel-tooling-model/src/main/java/org/apache/camel/tooling/model/PojoBeanModel.java
@@ -0,0 +1,46 @@
+/*
+ * 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.tooling.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PojoBeanModel extends BaseModel<PojoBeanModel.PojoBeanOptionModel> {
+
+    protected final List<PojoBeanModel.PojoBeanOptionModel> options = new ArrayList<>();
+
+    public PojoBeanModel() {
+    }
+
+    public void addOption(PojoBeanModel.PojoBeanOptionModel option) {
+        options.add(option);
+    }
+
+    @Override
+    public List<PojoBeanOptionModel> getOptions() {
+        return options;
+    }
+
+    @Override
+    public String getKind() {
+        return "bean";
+    }
+
+    public static class PojoBeanOptionModel extends BaseOptionModel {
+
+    }
+}
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
index f9d3e0f6400..a19a72ac9df 100644
--- 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
@@ -276,7 +276,7 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
 
         if (!model.getOptions().isEmpty()) {
             JsonObject options = JsonMapper.asJsonObject(model.getOptions());
-            jo.put("options", options);
+            jo.put("properties", options);
         }
 
         JsonObject root = new JsonObject();
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
index 6809cafa0c9..3a1561a74d0 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
@@ -49,6 +49,7 @@ import org.apache.camel.tooling.model.EipModel;
 import org.apache.camel.tooling.model.JsonMapper;
 import org.apache.camel.tooling.model.LanguageModel;
 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.tooling.util.FileUtil;
 import org.apache.camel.tooling.util.PackageHelper;
@@ -119,6 +120,12 @@ public class PrepareCatalogMojo extends AbstractMojo {
     @Parameter(defaultValue = "${project.basedir}/src/generated/resources/org/apache/camel/catalog/transformers")
     protected File transformersOutDir;
 
+    /**
+     * The output directory for pojo beans catalog
+     */
+    @Parameter(defaultValue = "${project.basedir}/src/generated/resources/org/apache/camel/catalog/beans")
+    protected File beansOutDir;
+
     /**
      * The output directory for dev-consoles catalog
      */
@@ -329,7 +336,7 @@ public class PrepareCatalogMojo extends AbstractMojo {
                                 allJsonFiles.add(p);
                             } else if (f.equals("component.properties") || f.equals("dataformat.properties")
                                     || f.equals("language.properties") || f.equals("other.properties")
-                                    || f.equals("transformer.properties")) {
+                                    || f.equals("transformer.properties") || f.equals("bean.properties")) {
                                 allPropertiesFiles.add(p);
                             }
                         });
@@ -381,6 +388,7 @@ public class PrepareCatalogMojo extends AbstractMojo {
             Set<String> dataformats = executeDataFormats();
             Set<String> languages = executeLanguages();
             Set<String> transformers = executeTransformers();
+            Set<String> beans = executeBeans();
             Set<String> consoles = executeDevConsoles();
             Set<String> others = executeOthers();
             executeDocuments(components, dataformats, languages, others);
@@ -771,6 +779,48 @@ public class PrepareCatalogMojo extends AbstractMojo {
         return transformerNames;
     }
 
+    protected Set<String> executeBeans() throws Exception {
+        Path beansOutDir = this.beansOutDir.toPath();
+
+        getLog().info("Copying all Camel pojo bean json descriptors");
+
+        // lets use sorted set/maps
+        Set<Path> jsonFiles;
+        Set<Path> duplicateJsonFiles;
+        Set<Path> beanFiles;
+
+        // find all beans from the components directory
+        beanFiles = allPropertiesFiles.stream().filter(p -> p.endsWith("bean.properties"))
+                .collect(Collectors.toCollection(TreeSet::new));
+        jsonFiles = allJsonFiles.stream().filter(p -> allModels.get(p) instanceof PojoBeanModel)
+                .collect(Collectors.toCollection(TreeSet::new));
+
+        getLog().info("Found " + beanFiles.size() + " bean.properties files");
+        getLog().info("Found " + jsonFiles.size() + " bean json files");
+
+        // make sure to create out dir
+        Files.createDirectories(beansOutDir);
+
+        // Check duplicates
+        duplicateJsonFiles = getDuplicates(jsonFiles);
+
+        // Copy all descriptors
+        Map<Path, Path> newJsons = map(jsonFiles, p -> p, p -> beansOutDir.resolve(p.getFileName()));
+        try (Stream<Path> stream = list(beansOutDir).filter(p -> !newJsons.containsValue(p))) {
+            stream.forEach(this::delete);
+        }
+        newJsons.forEach(this::copy);
+
+        Path all = beansOutDir.resolve("../beans.properties");
+        Set<String> beanNames
+                = jsonFiles.stream().map(PrepareCatalogMojo::asComponentName).collect(Collectors.toCollection(TreeSet::new));
+        FileUtil.updateFile(all, String.join("\n", beanNames) + "\n");
+
+        printBeansReport(jsonFiles, duplicateJsonFiles);
+
+        return beanNames;
+    }
+
     protected Set<String> executeDevConsoles() throws Exception {
         Path consolesOutDir = this.consolesOutDir.toPath();
 
@@ -1273,6 +1323,23 @@ public class PrepareCatalogMojo extends AbstractMojo {
         getLog().info(SEPARATOR);
     }
 
+    private void printBeansReport(
+            Set<Path> json, Set<Path> duplicate) {
+        getLog().info(SEPARATOR);
+        getLog().info("");
+        getLog().info("Camel pojo beans catalog report");
+        getLog().info("");
+        getLog().info("\tPojo beans found: " + json.size());
+        printComponentDebug(json);
+        if (!duplicate.isEmpty()) {
+            getLog().info("");
+            getLog().warn("\tDuplicate pojo beans detected: " + duplicate.size());
+            printComponentWarning(duplicate);
+        }
+        getLog().info("");
+        getLog().info(SEPARATOR);
+    }
+
     private void printConsolesReport(
             Set<Path> json, Set<Path> duplicate) {
         getLog().info(SEPARATOR);


(camel) 03/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0fca0b6bce39f10cf36cbf2be6e42ce9ee26b735
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 15:42:43 2024 +0100

    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.
---
 .../apache/camel/{beans.properties => bean.properties}    |  2 +-
 .../apache/camel/bean/UseOriginalAggregationStrategy.json | 15 +++++++++++++++
 .../META-INF/services/org/apache/camel/beans.properties   |  2 +-
 .../processor/aggregate/UseLatestAggregationStrategy.java |  2 +-
 .../aggregate/UseOriginalAggregationStrategy.java         |  5 +++++
 .../camel/maven/packaging/GeneratePojoBeanMojo.java       | 11 ++++++-----
 6 files changed, 29 insertions(+), 8 deletions(-)

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/bean.properties
similarity index 74%
copy from core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/beans.properties
copy to core/camel-core-processor/src/generated/resources/META-INF/services/org/apache/camel/bean.properties
index a4277ba5e66..348c3b28c96 100644
--- 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/bean.properties
@@ -1,5 +1,5 @@
 # Generated by camel build tools - do NOT edit this file!
-beans=org.apache.camel.processor.aggregate.UseLatestAggregationStrategy
+bean=UseLatestAggregationStrategy UseOriginalAggregationStrategy
 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
index a4277ba5e66..c8e1f79c503 100644
--- 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
@@ -1,5 +1,5 @@
 # Generated by camel build tools - do NOT edit this file!
-beans=org.apache.camel.processor.aggregate.UseLatestAggregationStrategy
+beans=UseLatestAggregationStrategy UseOriginalAggregationStrategy
 groupId=org.apache.camel
 artifactId=camel-core-processor
 version=4.5.0-SNAPSHOT
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 0b94b2b7441..d4ba479d3a7 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
@@ -26,7 +26,7 @@ import org.apache.camel.spi.Metadata;
  * 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", title = "Use Latest",
+@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.")
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..40689d482ab 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,7 @@ package org.apache.camel.processor.aggregate;
 
 import org.apache.camel.AggregationStrategy;
 import org.apache.camel.Exchange;
+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 +27,10 @@ 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.")
 public class UseOriginalAggregationStrategy implements AggregationStrategy {
 
     private final Exchange original;
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
index 879fe0df8a7..438b0de9744 100644
--- 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
@@ -160,17 +160,18 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
                         break;
                     }
                 }
+
                 // TODO: getter/setter for options ala EIP/components
                 models.add(model);
             }
         });
-        models.sort(Comparator.comparing(BeanPojoModel::getClassName));
+        models.sort(Comparator.comparing(BeanPojoModel::getName));
 
         if (!models.isEmpty()) {
             try {
                 StringJoiner names = new StringJoiner(" ");
                 for (var model : models) {
-                    names.add(model.getClassName());
+                    names.add(model.getName());
                     JsonObject jo = asJsonObject(model);
                     String json = jo.toJson();
                     json = Jsoner.prettyPrint(json, 2);
@@ -186,9 +187,9 @@ public class GeneratePojoBeanMojo extends AbstractGeneratorMojo {
                 // generate marker file
                 File camelMetaDir = new File(resourcesOutputDir, "META-INF/services/org/apache/camel/");
                 int count = models.size();
-                String properties = createProperties(project, "beans", names.toString());
-                updateResource(camelMetaDir.toPath(), "beans.properties", properties);
-                getLog().info("Generated beans.properties containing " + count + " Camel "
+                String properties = createProperties(project, "bean", names.toString());
+                updateResource(camelMetaDir.toPath(), "bean.properties", properties);
+                getLog().info("Generated bean.properties containing " + count + " Camel "
                               + (count > 1 ? "beans: " : "bean: ") + names);
             } catch (Exception e) {
                 throw new MojoExecutionException(e);


(camel) 10/10: 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.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 79d5117eeacd5163b5852dbc83c9288b86501e72
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Mar 14 19:47:37 2024 +0100

    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      |  1 +
 .../catalog/beans/ZipAggregationStrategy.json      | 16 +++++++++++++
 .../services/org/apache/camel/bean.properties      |  7 ++++++
 .../apache/camel/bean/ZipAggregationStrategy.json  | 16 +++++++++++++
 .../aggregate/zipfile/ZipAggregationStrategy.java  | 28 ++++++++++++++++++++++
 5 files changed, 68 insertions(+)

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
index 682e217224d..d3d0542f64e 100644
--- 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
@@ -8,3 +8,4 @@ MemoryIdempotentRepository
 StringAggregationStrategy
 UseLatestAggregationStrategy
 UseOriginalAggregationStrategy
+ZipAggregationStrategy
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..edd5aa7271d
--- /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/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..edd5aa7271d
--- /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/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..8e8467fe71e 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,7 @@ 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.Metadata;
 import org.apache.camel.spi.Synchronization;
 import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.util.FileUtil;
@@ -51,13 +52,24 @@ 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.")
 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 +162,22 @@ 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;
+    }
+
     @Override
     public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
         File zipFile;