You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ji...@apache.org on 2026/10/05 11:13:26 UTC
(camel-quarkus) branch camel-main updated (0cfcbc1796 -> 17c7dd0190)
This is an automated email from the ASF dual-hosted git repository.
JiriOndrusek pushed a change to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
discard 0cfcbc1796 Fixed snmp test module
discard 413fd6fbed Fixed jolt, rest test modules
discard 0478ca48a1 CAMEL-25197: cli-connector - use the Vert.x WebSocket client for the WebSocket transport
omit 2428783ab3 Regen
omit fba3d409d1 Regen
omit 717d928119 Regen
omit 10a4776107 Fixes #9231. Removed PQC native workarounds for BouncyCastle 1.86
omit 396b24ecd1 Regen
omit e6cd85fc4a Fixed crypto test modules and stale test categories
omit 11ee029aeb Regen
omit b60630bb99 fixed compulation error
omit 09aeb18675 Fixed sql test modules
omit 66928df3b5 Regen after rebase
omit 0276801328 Regen
omit cf7a07c1ca Regen
omit 0dbe846ee2 Upgrade Camel to 4.23.0-SNAPSHOT
omit abc21318a4 Fixes #9142. Delegate langchain4j-ingest to the camel-langchain4j-ingest component
add cafd3228ab Require JDK 21 as the minimum supported Java version
add 88e85ae1a1 Bump cq-plugin.version from 4.28.0 to 4.28.1
add f88809ef1f Upgrade hyperfoil-maven-plugin to 0.29.3
add 589ea3d7db Regen SBOM from commit f88809ef1f411afcb3b8885518cbcb8c1129bde2 (#9272)
new 53aea877b4 Fixes #9142. Delegate langchain4j-ingest to the camel-langchain4j-ingest component
new 028d4b0b34 CAMEL-25197: cli-connector - use the Vert.x WebSocket client for the WebSocket transport
new 2a50b1a67c Fixes #9231. Removed PQC native workarounds for BouncyCastle 1.86
new 17c7dd0190 Upgrade Camel to 4.23.0-SNAPSHOT
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (0cfcbc1796)
\
N -- N -- N refs/heads/camel-main (17c7dd0190)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 4 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.
Summary of changes:
.github/workflows/camel-master-cron.yaml | 40 +-
.github/workflows/check-dependency-convergence.yml | 4 +-
.github/workflows/ci-build.yaml | 46 +-
.github/workflows/generate-sbom-main.yml | 2 +-
.github/workflows/jdk21-build.yaml | 33 -
.github/workflows/pr-validate.yml | 6 +-
.github/workflows/quarkus-lts-ci-build.yaml | 24 +-
.github/workflows/quarkus-master-cron.yaml | 28 +-
.github/workflows/semeru17-build.yaml | 34 -
.sdkmanrc | 4 +-
AGENTS.md | 2 +-
Jenkinsfile | 2 +-
Jenkinsfile.sonarcloud | 2 +-
camel-quarkus-sbom/camel-quarkus-sbom.json | 34413 +++++++++---------
camel-quarkus-sbom/camel-quarkus-sbom.xml | 35262 ++++++++++---------
.../ROOT/pages/contributor-guide/index.adoc | 2 +-
.../ROOT/pages/reference/extensions/core.adoc | 2 +-
.../ROOT/pages/reference/extensions/ldap.adoc | 2 +-
.../modules/ROOT/pages/user-guide/first-steps.adoc | 2 +-
.../quarkus/core/deployment/util/CamelSupport.java | 2 +-
extensions/ldap/runtime/src/main/doc/usage.adoc | 2 +-
.../quarkus/component/seda/it/SedaRoutes.java | 9 +-
.../camel/quarkus/component/seda/it/SedaTest.java | 2 +-
.../component/seda/it/SedaVirtualThreadsIT.java | 10 +-
.../component/seda/it/SedaVirtualThreadsTest.java | 7 +-
integration-tests/infinispan/pom.xml | 16 -
pom.xml | 8 +-
.../quarkus/maven/UpdateBuildItemsDocMojo.java | 2 +-
.../doc-templates/extension-doc-page.adoc | 2 +-
.../cq-perf-regression-sample-base/pom.xml | 7 +-
30 files changed, 34977 insertions(+), 35000 deletions(-)
delete mode 100644 .github/workflows/jdk21-build.yaml
delete mode 100644 .github/workflows/semeru17-build.yaml
(camel-quarkus) 04/04: Upgrade Camel to 4.23.0-SNAPSHOT
Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
JiriOndrusek pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 17c7dd0190f6bdbe04ee1830ac6cda92bbbd0259
Author: Jiri Ondrusek <on...@gmail.com>
AuthorDate: Tue Aug 18 12:50:00 2026 +0200
Upgrade Camel to 4.23.0-SNAPSHOT
Co-Authored-By: Claude Fable 5.1 <no...@anthropic.com>
---
catalog/pom.xml | 143 ---
docs/antora.yml | 4 +-
.../ROOT/examples/components/digitalocean.yml | 13 -
.../examples/components/hazelcast-atomicvalue.yml | 13 -
.../examples/components/hazelcast-instance.yml | 4 +-
.../ROOT/examples/components/hazelcast-list.yml | 4 +-
.../ROOT/examples/components/hazelcast-map.yml | 4 +-
.../examples/components/hazelcast-multimap.yml | 4 +-
.../examples/components/hazelcast-pncounter.yml | 4 +-
.../ROOT/examples/components/hazelcast-queue.yml | 4 +-
.../components/hazelcast-replicatedmap.yml | 4 +-
.../examples/components/hazelcast-ringbuffer.yml | 4 +-
.../ROOT/examples/components/hazelcast-seda.yml | 4 +-
.../ROOT/examples/components/hazelcast-set.yml | 4 +-
.../ROOT/examples/components/hazelcast-topic.yml | 4 +-
.../ROOT/examples/components/iec60870-client.yml | 13 -
.../ROOT/examples/components/iec60870-server.yml | 13 -
docs/modules/ROOT/examples/components/irc.yml | 13 -
.../ROOT/examples/components/json-patch.yml | 13 -
.../examples/components/langchain4j-ingest.yml | 13 +
.../ROOT/examples/components/langchain4j-tools.yml | 13 -
docs/modules/ROOT/examples/components/minio.yml | 2 +-
docs/modules/ROOT/examples/components/openai.yml | 2 +-
docs/modules/ROOT/examples/components/splunk.yml | 13 -
docs/modules/ROOT/examples/languages/csimple.yml | 13 -
docs/modules/ROOT/examples/languages/java.yml | 2 +-
docs/modules/ROOT/examples/languages/joor.yml | 13 -
docs/modules/ROOT/examples/others/headersmap.yml | 13 -
docs/modules/ROOT/examples/others/leveldb.yml | 13 -
docs/modules/ROOT/examples/others/mcp-server.yml | 2 +-
.../examples/others/reactive-executor-vertx.yml | 13 -
.../examples/others/threadpoolfactory-vertx.yml | 13 -
docs/modules/ROOT/nav.adoc | 13 +-
.../ROOT/pages/contributor-guide/build-items.adoc | 25 -
.../ROOT/pages/reference/extensions/ai-tool.adoc | 2 +-
.../ROOT/pages/reference/extensions/core.adoc | 6 -
.../ROOT/pages/reference/extensions/csimple.adoc | 82 --
.../pages/reference/extensions/digitalocean.adoc | 52 -
.../ROOT/pages/reference/extensions/hazelcast.adoc | 13 +-
.../pages/reference/extensions/headersmap.adoc | 45 -
.../ROOT/pages/reference/extensions/iec60870.adoc | 42 -
.../ROOT/pages/reference/extensions/irc.adoc | 41 -
.../ROOT/pages/reference/extensions/joor.adoc | 9 +-
.../pages/reference/extensions/json-patch.adoc | 41 -
.../ROOT/pages/reference/extensions/jt400.adoc | 2 +-
.../reference/extensions/langchain4j-ingest.adoc | 24 +-
.../reference/extensions/langchain4j-tools.adoc | 74 --
.../ROOT/pages/reference/extensions/leveldb.adoc | 64 -
.../pages/reference/extensions/mcp-server.adoc | 2 +-
.../ROOT/pages/reference/extensions/minio.adoc | 6 +-
.../ROOT/pages/reference/extensions/openai.adoc | 7 +-
.../reference/extensions/reactive-executor.adoc | 46 -
.../ROOT/pages/reference/extensions/splunk.adoc | 52 -
.../extensions/threadpoolfactory-vertx.adoc | 46 -
.../quarkus/core/deployment/CamelProcessor.java | 6 -
.../spi/CompiledCSimpleExpressionBuildItem.java | 57 -
.../org/apache/camel/quarkus/core/CamelConfig.java | 22 -
extensions-core/pom.xml | 2 -
.../reactive-executor/deployment/pom.xml | 65 --
.../executor/deployment/BuildProcessor.java | 32 -
.../reactive/executor/deployment/Feature.java | 29 -
extensions-core/reactive-executor/pom.xml | 40 -
extensions-core/reactive-executor/runtime/pom.xml | 78 --
.../executor/ReactiveExecutorRecorder.java | 39 -
.../main/resources/META-INF/quarkus-extension.yaml | 36 -
.../threadpoolfactory-vertx/deployment/pom.xml | 65 --
.../ThreadpoolfactoryVertxProcessor.java | 42 -
extensions-core/threadpoolfactory-vertx/pom.xml | 37 -
.../threadpoolfactory-vertx/runtime/pom.xml | 76 --
.../vertx/ThreadPoolFactoryVertxRecorder.java | 39 -
.../main/resources/META-INF/quarkus-extension.yaml | 36 -
.../console/ConsoleEnabledWithDevProfileTest.java | 5 +-
.../component/console/CamelConsoleRecorder.java | 1 -
.../console/QuarkusPropertiesDevConsole.java | 56 -
extensions-jvm/iec60870/deployment/pom.xml | 61 -
.../iec60870/deployment/Iec60870Processor.java | 46 -
extensions-jvm/iec60870/pom.xml | 37 -
extensions-jvm/iec60870/runtime/pom.xml | 70 --
.../main/resources/META-INF/quarkus-extension.yaml | 37 -
extensions-jvm/irc/deployment/pom.xml | 61 -
.../component/irc/deployment/IrcProcessor.java | 46 -
extensions-jvm/irc/pom.xml | 37 -
extensions-jvm/irc/runtime/pom.xml | 69 --
.../main/resources/META-INF/quarkus-extension.yaml | 37 -
extensions-jvm/json-patch/deployment/pom.xml | 61 -
.../json/patch/deployment/JsonPatchProcessor.java | 46 -
extensions-jvm/json-patch/pom.xml | 37 -
extensions-jvm/json-patch/runtime/pom.xml | 70 --
.../main/resources/META-INF/quarkus-extension.yaml | 37 -
extensions-jvm/pom.xml | 3 -
extensions/ai-tool/runtime/src/main/doc/usage.adoc | 2 +-
.../crypto/deployment/CryptoProcessor.java | 8 +
extensions/csimple/deployment/pom.xml | 65 --
.../CSimpleExpressionSourceBuildItem.java | 58 -
.../csimple/deployment/CSimpleProcessor.java | 279 -----
extensions/csimple/pom.xml | 37 -
extensions/csimple/runtime/pom.xml | 72 --
.../csimple/runtime/src/main/doc/limitations.adoc | 32 -
.../component/csimple/CSimpleLanguageRecorder.java | 40 -
.../main/resources/META-INF/quarkus-extension.yaml | 36 -
extensions/digitalocean/deployment/pom.xml | 69 --
.../deployment/DigitaloceanProcessor.java | 59 -
extensions/digitalocean/pom.xml | 37 -
extensions/digitalocean/runtime/pom.xml | 78 --
.../main/resources/META-INF/quarkus-extension.yaml | 36 -
extensions/hazelcast/deployment/pom.xml | 2 +-
extensions/hazelcast/pom.xml | 2 +-
extensions/hazelcast/runtime/pom.xml | 4 +-
.../main/resources/META-INF/quarkus-extension.yaml | 4 +-
extensions/headersmap/deployment/pom.xml | 61 -
.../headersmap/deployment/HeadersmapProcessor.java | 40 -
extensions/headersmap/pom.xml | 37 -
extensions/headersmap/runtime/pom.xml | 75 --
.../headersmap/CamelHeadersmapRecorder.java | 36 -
.../ThreadedLRUCacheStrategySubstitutions.java | 40 -
.../main/resources/META-INF/quarkus-extension.yaml | 36 -
.../component/jolt/deployment/JoltProcessor.java | 2 +-
.../main/resources/META-INF/quarkus-extension.yaml | 2 +-
extensions/langchain4j-ingest/runtime/pom.xml | 2 +-
.../main/resources/META-INF/quarkus-extension.yaml | 2 +-
extensions/langchain4j-tools/deployment/pom.xml | 65 --
.../deployment/Langchain4jToolsProcessor.java | 29 -
extensions/langchain4j-tools/pom.xml | 37 -
extensions/langchain4j-tools/runtime/pom.xml | 104 --
.../main/resources/META-INF/quarkus-extension.yaml | 36 -
extensions/leveldb/deployment/pom.xml | 65 --
.../leveldb/deployment/LeveldbProcessor.java | 51 -
extensions/leveldb/pom.xml | 37 -
extensions/leveldb/runtime/pom.xml | 84 --
.../leveldb/runtime/src/main/doc/limitations.adoc | 14 -
.../QuarkusLevelDBAggregationRepository.java | 71 --
.../main/resources/META-INF/quarkus-extension.yaml | 36 -
extensions/mcp-server/runtime/pom.xml | 2 +-
.../main/resources/META-INF/quarkus-extension.yaml | 2 +-
.../main/resources/META-INF/quarkus-extension.yaml | 2 +-
extensions/openai/runtime/pom.xml | 2 +-
.../main/resources/META-INF/quarkus-extension.yaml | 2 +-
extensions/pom.xml | 6 -
extensions/splunk/deployment/pom.xml | 61 -
.../splunk/deployment/SplunkProcessor.java | 96 --
extensions/splunk/pom.xml | 37 -
extensions/splunk/runtime/pom.xml | 71 --
.../main/resources/META-INF/quarkus-extension.yaml | 36 -
.../src/main/resources/application.properties | 3 +
integration-tests-jvm/iec60870/pom.xml | 83 --
.../component/iec60870/it/Iec60870Resource.java | 63 -
.../component/iec60870/it/Iec60870Test.java | 42 -
integration-tests-jvm/irc/pom.xml | 83 --
.../quarkus/component/irc/it/IrcResource.java | 50 -
.../camel/quarkus/component/irc/it/IrcTest.java | 34 -
integration-tests-jvm/json-patch/pom.xml | 82 --
.../component/json/patch/it/JsonPatchResource.java | 50 -
.../component/json/patch/it/JsonPatchTest.java | 34 -
integration-tests-jvm/pom.xml | 3 -
.../component/snmp/it/SnmpTestResource.java | 25 +-
integration-tests/avro/pom.xml | 3 +-
.../camel/quarkus/component/avro/it/AvroTest.java | 2 +
integration-tests/csimple/pom.xml | 195 ----
.../component/csimple/it/CSimpleResource.java | 73 --
.../quarkus/component/csimple/it/CSimpleRoute.java | 45 -
.../src/main/resources/application.properties | 18 -
.../src/main/resources/routes/my-routes.xml | 34 -
.../src/main/resources/routes/my-routes.yaml | 23 -
.../quarkus/component/csimple/it/CSimpleIT.java | 24 -
.../quarkus/component/csimple/it/CSimpleTest.java | 87 --
integration-tests/digitalocean/README.adoc | 14 -
integration-tests/digitalocean/pom.xml | 156 ---
.../digitalocean/it/DigitalOceanClientMock.java | 47 -
.../digitalocean/it/DigitaloceanResource.java | 554 ---------
.../digitalocean/it/DigitaloceanRoute.java | 83 --
.../component/digitalocean/it/MockApiService.java | 32 -
.../digitalocean/it/DigitaloceanDropletIT.java | 23 -
.../digitalocean/it/DigitaloceanDropletTest.java | 452 --------
.../component/digitalocean/it/DigitaloceanIT.java | 24 -
.../digitalocean/it/DigitaloceanTest.java | 166 ---
.../digitalocean/it/DigitaloceanTestResource.java | 35 -
.../src/test/resources/mappings/account.json | 28 -
.../src/test/resources/mappings/action.json | 28 -
.../test/resources/mappings/actionFloatingIp.json | 28 -
.../src/test/resources/mappings/actions.json | 28 -
.../resources/mappings/actionsBlockStorage.json | 28 -
.../test/resources/mappings/actionsDroplet.json | 28 -
.../test/resources/mappings/backupsDroplet.json | 28 -
.../resources/mappings/createBlockStorage.json | 28 -
.../src/test/resources/mappings/createDroplet.json | 28 -
.../test/resources/mappings/createFloatingIp.json | 28 -
.../src/test/resources/mappings/createKey.json | 28 -
.../src/test/resources/mappings/createTag.json | 28 -
.../resources/mappings/deleteBlockStorage.json | 28 -
.../src/test/resources/mappings/deleteDroplet.json | 28 -
.../test/resources/mappings/deleteFloatingIp.json | 28 -
.../src/test/resources/mappings/deleteKey.json | 28 -
.../test/resources/mappings/deleteSnapshot.json | 28 -
.../src/test/resources/mappings/deleteTag.json | 28 -
.../src/test/resources/mappings/dropletAction.json | 28 -
.../mappings/getAllActionsFloatingIp.json | 28 -
.../resources/mappings/getAllBlockstorages.json | 28 -
.../test/resources/mappings/getAllFloatingIps.json | 28 -
.../src/test/resources/mappings/getAllKeys.json | 28 -
.../src/test/resources/mappings/getAllTags.json | 28 -
.../test/resources/mappings/getBlockStorage.json | 28 -
.../src/test/resources/mappings/getDroplet.json | 28 -
.../src/test/resources/mappings/getFloatingIp.json | 28 -
.../src/test/resources/mappings/getKey.json | 28 -
.../src/test/resources/mappings/getTag.json | 28 -
.../src/test/resources/mappings/imageById.json | 28 -
.../src/test/resources/mappings/images.json | 28 -
.../test/resources/mappings/images_private.json | 28 -
.../test/resources/mappings/neighborsDroplet.json | 28 -
.../src/test/resources/mappings/regions.json | 28 -
.../src/test/resources/mappings/sizes.json | 28 -
.../src/test/resources/mappings/snapshotById.json | 28 -
.../src/test/resources/mappings/snapshots.json | 28 -
.../test/resources/mappings/snapshotsDroplet.json | 28 -
.../src/test/resources/mappings/updateKey.json | 28 -
.../hazelcast/it/HazelcastAtomicResource.java | 88 --
.../component/hazelcast/it/HazelcastRoutes.java | 7 -
.../component/hazelcast/it/HazelcastAtomicIT.java | 26 -
.../hazelcast/it/HazelcastAtomicTest.java | 72 --
integration-tests/headersmap/pom.xml | 110 --
.../headersmap/it/HeadersmapResource.java | 42 -
.../component/headersmap/it/HeadersmapIT.java | 24 -
.../component/headersmap/it/HeadersmapTest.java | 85 --
integration-tests/langchain4j-agent-ql4j/pom.xml | 17 -
integration-tests/langchain4j-tools/README.adoc | 20 -
integration-tests/langchain4j-tools/pom.xml | 161 ---
.../tools/it/Langchain4jToolsProducers.java | 41 -
.../tools/it/Langchain4jToolsResource.java | 83 --
.../tools/it/Langchain4jToolsRoutes.java | 31 -
.../src/main/resources/application.properties | 20 -
.../src/main/resources/sql/db-init.sql | 30 -
.../langchain4j/tools/it/Langchain4jToolsIT.java | 24 -
.../langchain4j/tools/it/Langchain4jToolsTest.java | 41 -
.../langchain4j/tools/it/OllamaTestResource.java | 49 -
..._chat-3a96d932-0bd9-45c0-8482-0fdc0cc67243.json | 26 -
..._chat-58a8c909-b8c3-4e57-946a-110a8c6a6fab.json | 27 -
integration-tests/leveldb/pom.xml | 149 ---
.../component/leveldb/it/LeveldbResource.java | 135 ---
.../component/leveldb/it/LeveldbRouteBuilder.java | 127 --
.../quarkus/component/leveldb/it/LeveldbIT.java | 23 -
.../quarkus/component/leveldb/it/LeveldbTest.java | 146 ---
integration-tests/main/pom.xml | 34 -
.../camel/quarkus/main/CoreMainResource.java | 24 -
.../apache/camel/quarkus/main/CoreMainTest.java | 19 +-
integration-tests/pom.xml | 6 -
.../quarkus/component/rest/it/RestRoutes.java | 2 +-
integration-tests/splunk/README.adoc | 6 -
integration-tests/splunk/pom.xml | 162 ---
.../component/splunk/it/SplunkResource.java | 194 ----
.../src/main/resources/application.properties | 17 -
.../quarkus/component/splunk/it/SplunkIT.java | 25 -
.../quarkus/component/splunk/it/SplunkTest.java | 221 ----
.../splunk/src/test/resources/default.yml | 75 --
.../camel/quarkus/component/sql/it/SqlRoutes.java | 2 +-
pom.xml | 22 +-
poms/bom/pom.xml | 235 +---
poms/bom/src/main/generated/flattened-full-pom.xml | 1224 +++++++++-----------
.../src/main/generated/flattened-reduced-pom.xml | 1074 ++++++++---------
.../generated/flattened-reduced-verbose-pom.xml | 1092 ++++++++---------
poms/build-parent-it/pom.xml | 16 +
.../org/apache/camel/quarkus/maven/CqCatalog.java | 10 +-
tooling/scripts/test-categories.yaml | 6 -
262 files changed, 1679 insertions(+), 12930 deletions(-)
diff --git a/catalog/pom.xml b/catalog/pom.xml
index 4ccffec772..5561f9cc34 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -1020,19 +1020,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-csimple</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-csv</artifactId>
@@ -1215,19 +1202,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-digitalocean</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-direct</artifactId>
@@ -1774,19 +1748,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-headersmap</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-hl7</artifactId>
@@ -1904,19 +1865,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-iec60870</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-ignite</artifactId>
@@ -1982,19 +1930,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-irc</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-iso8583</artifactId>
@@ -2320,19 +2255,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-json-patch</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-json-validator</artifactId>
@@ -2632,19 +2554,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-langchain4j-tools</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-langchain4j-web-search</artifactId>
@@ -2697,19 +2606,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-leveldb</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-log</artifactId>
@@ -3516,19 +3412,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-reactive-executor</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-reactive-streams</artifactId>
@@ -3906,19 +3789,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-splunk</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-splunk-hec</artifactId>
@@ -4504,19 +4374,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-threadpoolfactory-vertx</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-thrift</artifactId>
diff --git a/docs/antora.yml b/docs/antora.yml
index c159012c1c..c8b8d8ed2b 100644
--- a/docs/antora.yml
+++ b/docs/antora.yml
@@ -28,8 +28,8 @@ asciidoc:
requires: "'util=camel-website-util,quarkus=xref:js/quarkus.js'"
# Project versions
- camel-version: 4.22.1 # replace ${camel.version}
- camel-docs-version: 4.22.x
+ camel-version: 4.23.0-SNAPSHOT # replace ${camel.version}
+ camel-docs-version: next
camel-quarkus-version: 4.0.0 # replace ${camel-quarkus.version}
quarkus-version: 3.40.1 # replace ${quarkus.version}
graalvm-version: 25.0.4.1 # replace ${graalvm.version}
diff --git a/docs/modules/ROOT/examples/components/digitalocean.yml b/docs/modules/ROOT/examples/components/digitalocean.yml
deleted file mode 100644
index b7266954b3..0000000000
--- a/docs/modules/ROOT/examples/components/digitalocean.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-digitalocean
-cqArtifactIdBase: digitalocean
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 1.1.0
-cqNativeSince: 2.0.0
-cqCamelPartName: digitalocean
-cqCamelPartTitle: DigitalOcean
-cqCamelPartDescription: Manage Droplets and resources within the DigitalOcean cloud.
-cqExtensionPageTitle: DigitalOcean
diff --git a/docs/modules/ROOT/examples/components/hazelcast-atomicvalue.yml b/docs/modules/ROOT/examples/components/hazelcast-atomicvalue.yml
deleted file mode 100644
index ef1db7f6ad..0000000000
--- a/docs/modules/ROOT/examples/components/hazelcast-atomicvalue.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-hazelcast
-cqArtifactIdBase: hazelcast
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 1.1.0
-cqNativeSince: 1.6.0
-cqCamelPartName: hazelcast-atomicvalue
-cqCamelPartTitle: Hazelcast Atomic Number
-cqCamelPartDescription: Increment, decrement, set, etc. Hazelcast atomic number (a grid wide number).
-cqExtensionPageTitle: Hazelcast Atomic Number
diff --git a/docs/modules/ROOT/examples/components/hazelcast-instance.yml b/docs/modules/ROOT/examples/components/hazelcast-instance.yml
index 4fd4202fd9..b2f86d3f67 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-instance.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-instance.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-instance
cqCamelPartTitle: Hazelcast Instance
cqCamelPartDescription: Consume join/leave events of a cache instance in a Hazelcast cluster.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-list.yml b/docs/modules/ROOT/examples/components/hazelcast-list.yml
index b1deb397b1..2fc6f659bc 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-list.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-list.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-list
cqCamelPartTitle: Hazelcast List
cqCamelPartDescription: Perform operations on Hazelcast distributed list.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-map.yml b/docs/modules/ROOT/examples/components/hazelcast-map.yml
index 5097bfebce..bf16073bb6 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-map.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-map.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-map
cqCamelPartTitle: Hazelcast Map
cqCamelPartDescription: Perform operations on Hazelcast distributed map.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-multimap.yml b/docs/modules/ROOT/examples/components/hazelcast-multimap.yml
index b03928ee99..05479795aa 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-multimap.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-multimap.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-multimap
cqCamelPartTitle: Hazelcast Multimap
cqCamelPartDescription: Perform operations on Hazelcast distributed multimap.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-pncounter.yml b/docs/modules/ROOT/examples/components/hazelcast-pncounter.yml
index 1b87a65b34..0c22cc8e86 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-pncounter.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-pncounter.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-pncounter
cqCamelPartTitle: Hazelcast PN Counter
cqCamelPartDescription: Increment, decrement, get, etc. operations on a Hazelcast PN Counter (CRDT counter).
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-queue.yml b/docs/modules/ROOT/examples/components/hazelcast-queue.yml
index 156e77193f..8c40f29dc6 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-queue.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-queue.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-queue
cqCamelPartTitle: Hazelcast Queue
cqCamelPartDescription: Perform operations on Hazelcast distributed queue.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-replicatedmap.yml b/docs/modules/ROOT/examples/components/hazelcast-replicatedmap.yml
index b1b1192372..5bb36953a3 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-replicatedmap.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-replicatedmap.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-replicatedmap
cqCamelPartTitle: Hazelcast Replicated Map
cqCamelPartDescription: Perform operations on Hazelcast replicated map.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-ringbuffer.yml b/docs/modules/ROOT/examples/components/hazelcast-ringbuffer.yml
index df871100b2..3c4c8c60a8 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-ringbuffer.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-ringbuffer.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-ringbuffer
cqCamelPartTitle: Hazelcast Ringbuffer
cqCamelPartDescription: Perform operations on Hazelcast distributed ringbuffer.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-seda.yml b/docs/modules/ROOT/examples/components/hazelcast-seda.yml
index c07e0ad3ac..b5da7f9a65 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-seda.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-seda.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-seda
cqCamelPartTitle: Hazelcast SEDA
cqCamelPartDescription: Asynchronously send/receive Exchanges between Camel routes running on potentially distinct JVMs/hosts backed by Hazelcast BlockingQueue.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-set.yml b/docs/modules/ROOT/examples/components/hazelcast-set.yml
index dad804e2ef..34636daac3 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-set.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-set.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-set
cqCamelPartTitle: Hazelcast Set
cqCamelPartDescription: Perform operations on Hazelcast distributed set.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/hazelcast-topic.yml b/docs/modules/ROOT/examples/components/hazelcast-topic.yml
index 9cb77d3195..037ff32ce1 100644
--- a/docs/modules/ROOT/examples/components/hazelcast-topic.yml
+++ b/docs/modules/ROOT/examples/components/hazelcast-topic.yml
@@ -4,10 +4,10 @@ cqArtifactId: camel-quarkus-hazelcast
cqArtifactIdBase: hazelcast
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 1.1.0
cqNativeSince: 1.6.0
cqCamelPartName: hazelcast-topic
cqCamelPartTitle: Hazelcast Topic
cqCamelPartDescription: Send and receive messages to/from Hazelcast distributed topic.
-cqExtensionPageTitle: Hazelcast Atomic Number
+cqExtensionPageTitle: Hazelcast
diff --git a/docs/modules/ROOT/examples/components/iec60870-client.yml b/docs/modules/ROOT/examples/components/iec60870-client.yml
deleted file mode 100644
index 5f9fd3479b..0000000000
--- a/docs/modules/ROOT/examples/components/iec60870-client.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-iec60870
-cqArtifactIdBase: iec60870
-cqNativeSupported: false
-cqStatus: Preview
-cqDeprecated: true
-cqJvmSince: 1.1.0
-cqNativeSince: n/a
-cqCamelPartName: iec60870-client
-cqCamelPartTitle: IEC 60870 Client
-cqCamelPartDescription: IEC 60870 supervisory control and data acquisition (SCADA) client using NeoSCADA implementation.
-cqExtensionPageTitle: IEC 60870 Client
diff --git a/docs/modules/ROOT/examples/components/iec60870-server.yml b/docs/modules/ROOT/examples/components/iec60870-server.yml
deleted file mode 100644
index 78522e2aed..0000000000
--- a/docs/modules/ROOT/examples/components/iec60870-server.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-iec60870
-cqArtifactIdBase: iec60870
-cqNativeSupported: false
-cqStatus: Preview
-cqDeprecated: true
-cqJvmSince: 1.1.0
-cqNativeSince: n/a
-cqCamelPartName: iec60870-server
-cqCamelPartTitle: IEC 60870 Server
-cqCamelPartDescription: IEC 60870 supervisory control and data acquisition (SCADA) server using NeoSCADA implementation.
-cqExtensionPageTitle: IEC 60870 Client
diff --git a/docs/modules/ROOT/examples/components/irc.yml b/docs/modules/ROOT/examples/components/irc.yml
deleted file mode 100644
index 9c9e7c4583..0000000000
--- a/docs/modules/ROOT/examples/components/irc.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-irc
-cqArtifactIdBase: irc
-cqNativeSupported: false
-cqStatus: Preview
-cqDeprecated: true
-cqJvmSince: 1.1.0
-cqNativeSince: n/a
-cqCamelPartName: irc
-cqCamelPartTitle: IRC
-cqCamelPartDescription: Send and receive messages to/from an IRC chat.
-cqExtensionPageTitle: IRC
diff --git a/docs/modules/ROOT/examples/components/json-patch.yml b/docs/modules/ROOT/examples/components/json-patch.yml
deleted file mode 100644
index e83ce4946f..0000000000
--- a/docs/modules/ROOT/examples/components/json-patch.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-json-patch
-cqArtifactIdBase: json-patch
-cqNativeSupported: false
-cqStatus: Preview
-cqDeprecated: true
-cqJvmSince: 2.7.0
-cqNativeSince: n/a
-cqCamelPartName: json-patch
-cqCamelPartTitle: JsonPatch
-cqCamelPartDescription: Transforms JSON using JSON patch (RFC 6902).
-cqExtensionPageTitle: JsonPatch
diff --git a/docs/modules/ROOT/examples/components/langchain4j-ingest.yml b/docs/modules/ROOT/examples/components/langchain4j-ingest.yml
new file mode 100644
index 0000000000..e4b6c728a7
--- /dev/null
+++ b/docs/modules/ROOT/examples/components/langchain4j-ingest.yml
@@ -0,0 +1,13 @@
+# Do not edit directly!
+# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
+cqArtifactId: camel-quarkus-langchain4j-ingest
+cqArtifactIdBase: langchain4j-ingest
+cqNativeSupported: true
+cqStatus: Stable
+cqDeprecated: false
+cqJvmSince: 3.39.0
+cqNativeSince: 3.39.0
+cqCamelPartName: langchain4j-ingest
+cqCamelPartTitle: LangChain4j Ingest
+cqCamelPartDescription: Ingest documents into a LangChain4j EmbeddingStore: split, embed and store the message body.
+cqExtensionPageTitle: LangChain4j Ingest
diff --git a/docs/modules/ROOT/examples/components/langchain4j-tools.yml b/docs/modules/ROOT/examples/components/langchain4j-tools.yml
deleted file mode 100644
index c860e13a10..0000000000
--- a/docs/modules/ROOT/examples/components/langchain4j-tools.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-langchain4j-tools
-cqArtifactIdBase: langchain4j-tools
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 3.15.0
-cqNativeSince: 3.24.0
-cqCamelPartName: langchain4j-tools
-cqCamelPartTitle: LangChain4j Tools
-cqCamelPartDescription: LangChain4j Tools and Function Calling Features
-cqExtensionPageTitle: LangChain4j Tools
diff --git a/docs/modules/ROOT/examples/components/minio.yml b/docs/modules/ROOT/examples/components/minio.yml
index 3448c25d3d..b4787b6719 100644
--- a/docs/modules/ROOT/examples/components/minio.yml
+++ b/docs/modules/ROOT/examples/components/minio.yml
@@ -4,7 +4,7 @@ cqArtifactId: camel-quarkus-minio
cqArtifactIdBase: minio
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: false
+cqDeprecated: true
cqJvmSince: 1.5.0
cqNativeSince: 1.6.0
cqCamelPartName: minio
diff --git a/docs/modules/ROOT/examples/components/openai.yml b/docs/modules/ROOT/examples/components/openai.yml
index a3e8cf3ff0..59090bc765 100644
--- a/docs/modules/ROOT/examples/components/openai.yml
+++ b/docs/modules/ROOT/examples/components/openai.yml
@@ -9,5 +9,5 @@ cqJvmSince: 3.32.0
cqNativeSince: 3.32.0
cqCamelPartName: openai
cqCamelPartTitle: OpenAI
-cqCamelPartDescription: OpenAI endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech.
+cqCamelPartDescription: LLM endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech using OpenAI-compatible APIs. The openai scheme is a supported alias.
cqExtensionPageTitle: OpenAI
diff --git a/docs/modules/ROOT/examples/components/splunk.yml b/docs/modules/ROOT/examples/components/splunk.yml
deleted file mode 100644
index 5b579e886b..0000000000
--- a/docs/modules/ROOT/examples/components/splunk.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-splunk
-cqArtifactIdBase: splunk
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 1.8.0
-cqNativeSince: 1.8.0
-cqCamelPartName: splunk
-cqCamelPartTitle: Splunk
-cqCamelPartDescription: Publish or search for events in Splunk.
-cqExtensionPageTitle: Splunk
diff --git a/docs/modules/ROOT/examples/languages/csimple.yml b/docs/modules/ROOT/examples/languages/csimple.yml
deleted file mode 100644
index af6eb8493b..0000000000
--- a/docs/modules/ROOT/examples/languages/csimple.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-csimple
-cqArtifactIdBase: csimple
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 1.5.0
-cqNativeSince: 1.5.0
-cqCamelPartName: csimple
-cqCamelPartTitle: CSimple
-cqCamelPartDescription: Evaluate a compiled simple expression
-cqExtensionPageTitle: CSimple
diff --git a/docs/modules/ROOT/examples/languages/java.yml b/docs/modules/ROOT/examples/languages/java.yml
index 6d75ea8739..ad8fd5101b 100644
--- a/docs/modules/ROOT/examples/languages/java.yml
+++ b/docs/modules/ROOT/examples/languages/java.yml
@@ -4,7 +4,7 @@ cqArtifactId: camel-quarkus-joor
cqArtifactIdBase: joor
cqNativeSupported: true
cqStatus: Stable
-cqDeprecated: true
+cqDeprecated: false
cqJvmSince: 2.0.0
cqNativeSince: 3.2.0
cqCamelPartName: java
diff --git a/docs/modules/ROOT/examples/languages/joor.yml b/docs/modules/ROOT/examples/languages/joor.yml
deleted file mode 100644
index 0e42cbae5a..0000000000
--- a/docs/modules/ROOT/examples/languages/joor.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-joor
-cqArtifactIdBase: joor
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 2.0.0
-cqNativeSince: 3.2.0
-cqCamelPartName: joor
-cqCamelPartTitle: jOOR
-cqCamelPartDescription: Evaluates a jOOR (Java compiled once at runtime) expression
-cqExtensionPageTitle: jOOR
diff --git a/docs/modules/ROOT/examples/others/headersmap.yml b/docs/modules/ROOT/examples/others/headersmap.yml
deleted file mode 100644
index 5cf3663e2f..0000000000
--- a/docs/modules/ROOT/examples/others/headersmap.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-headersmap
-cqArtifactIdBase: headersmap
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 1.2.0
-cqNativeSince: 1.2.0
-cqCamelPartName: headersmap
-cqCamelPartTitle: Headersmap
-cqCamelPartDescription: Fast case-insensitive headers map implementation
-cqExtensionPageTitle: Headersmap
diff --git a/docs/modules/ROOT/examples/others/leveldb.yml b/docs/modules/ROOT/examples/others/leveldb.yml
deleted file mode 100644
index a025a5f1ee..0000000000
--- a/docs/modules/ROOT/examples/others/leveldb.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-leveldb
-cqArtifactIdBase: leveldb
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 1.2.0
-cqNativeSince: 1.2.0
-cqCamelPartName: leveldb
-cqCamelPartTitle: LevelDB
-cqCamelPartDescription: Using LevelDB as persistent EIP store
-cqExtensionPageTitle: LevelDB
diff --git a/docs/modules/ROOT/examples/others/mcp-server.yml b/docs/modules/ROOT/examples/others/mcp-server.yml
index 596ae964bf..243dcf3408 100644
--- a/docs/modules/ROOT/examples/others/mcp-server.yml
+++ b/docs/modules/ROOT/examples/others/mcp-server.yml
@@ -9,5 +9,5 @@ cqJvmSince: 3.39.0
cqNativeSince: 3.39.0
cqCamelPartName: mcp-server
cqCamelPartTitle: MCP Server
-cqCamelPartDescription: Expose ai-tool routes as MCP tools over streamable HTTP
+cqCamelPartDescription: Expose ai-tool routes as MCP tools and ai-resource routes as MCP resources over streamable HTTP
cqExtensionPageTitle: MCP Server
diff --git a/docs/modules/ROOT/examples/others/reactive-executor-vertx.yml b/docs/modules/ROOT/examples/others/reactive-executor-vertx.yml
deleted file mode 100644
index bffd915ef4..0000000000
--- a/docs/modules/ROOT/examples/others/reactive-executor-vertx.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-reactive-executor
-cqArtifactIdBase: reactive-executor
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 0.3.0
-cqNativeSince: 0.3.0
-cqCamelPartName: reactive-executor-vertx
-cqCamelPartTitle: Reactive Executor Vert.x
-cqCamelPartDescription: Reactive Executor for camel-core using Vert.x
-cqExtensionPageTitle: Reactive Executor
diff --git a/docs/modules/ROOT/examples/others/threadpoolfactory-vertx.yml b/docs/modules/ROOT/examples/others/threadpoolfactory-vertx.yml
deleted file mode 100644
index 45d4f4938c..0000000000
--- a/docs/modules/ROOT/examples/others/threadpoolfactory-vertx.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Do not edit directly!
-# This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-cqArtifactId: camel-quarkus-threadpoolfactory-vertx
-cqArtifactIdBase: threadpoolfactory-vertx
-cqNativeSupported: true
-cqStatus: Stable
-cqDeprecated: true
-cqJvmSince: 1.0.0
-cqNativeSince: 1.0.0
-cqCamelPartName: threadpoolfactory-vertx
-cqCamelPartTitle: ThreadPoolFactory Vert.x
-cqCamelPartDescription: ThreadPoolFactory for camel-core using Vert.x
-cqExtensionPageTitle: ThreadPoolFactory Vert.x
diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc
index ca3d148479..398d03abb1 100644
--- a/docs/modules/ROOT/nav.adoc
+++ b/docs/modules/ROOT/nav.adoc
@@ -89,7 +89,6 @@
*** xref:reference/extensions/cli-debug.adoc[CLI Debug]
*** xref:reference/extensions/cm-sms.adoc[CM SMS Gateway]
*** xref:reference/extensions/csv.adoc[CSV]
-*** xref:reference/extensions/csimple.adoc[CSimple]
*** xref:reference/extensions/cxf-soap.adoc[CXF]
*** xref:reference/extensions/caffeine.adoc[Caffeine Cache]
*** xref:reference/extensions/cassandraql.adoc[Cassandra CQL]
@@ -121,7 +120,6 @@
*** xref:reference/extensions/debug.adoc[Debug]
*** xref:reference/extensions/djl.adoc[Deep Java Library]
*** xref:reference/extensions/diagram.adoc[Diagram]
-*** xref:reference/extensions/digitalocean.adoc[DigitalOcean]
*** xref:reference/extensions/direct.adoc[Direct]
*** xref:reference/extensions/disruptor.adoc[Disruptor]
*** xref:reference/extensions/docling.adoc[Docling]
@@ -160,14 +158,11 @@
*** xref:reference/extensions/hl7.adoc[HL7]
*** xref:reference/extensions/http.adoc[HTTP]
*** xref:reference/extensions/hashicorp-vault.adoc[Hashicorp Vault]
-*** xref:reference/extensions/hazelcast.adoc[Hazelcast Atomic Number]
-*** xref:reference/extensions/headersmap.adoc[Headersmap]
+*** xref:reference/extensions/hazelcast.adoc[Hazelcast]
*** xref:reference/extensions/ibm-cos.adoc[IBM Cloud Object Storage]
*** xref:reference/extensions/ibm-secrets-manager.adoc[IBM Secrets Manager]
*** xref:reference/extensions/ibm-watson-discovery.adoc[IBM Watson Discovery]
*** xref:reference/extensions/ibm-watson-language.adoc[IBM Watson Language]
-*** xref:reference/extensions/iec60870.adoc[IEC 60870 Client]
-*** xref:reference/extensions/irc.adoc[IRC]
*** xref:reference/extensions/iso8583.adoc[ISO-8583]
*** xref:reference/extensions/ignite.adoc[Ignite Cache]
*** xref:reference/extensions/infinispan.adoc[Infinispan]
@@ -201,7 +196,6 @@
*** xref:reference/extensions/jfr.adoc[Jfr]
*** xref:reference/extensions/jira.adoc[Jira]
*** xref:reference/extensions/jolokia.adoc[Jolokia]
-*** xref:reference/extensions/json-patch.adoc[JsonPatch]
*** xref:reference/extensions/jsoup.adoc[Jsoup]
*** xref:reference/extensions/kafka.adoc[Kafka]
*** xref:reference/extensions/kamelet.adoc[Kamelet]
@@ -222,10 +216,8 @@
*** xref:reference/extensions/langchain4j-embeddings.adoc[LangChain4j Embeddings]
*** xref:reference/extensions/langchain4j-ingest.adoc[LangChain4j Ingest]
*** xref:reference/extensions/langchain4j-tokenizer.adoc[LangChain4j Tokenizer]
-*** xref:reference/extensions/langchain4j-tools.adoc[LangChain4j Tools]
*** xref:reference/extensions/langchain4j-web-search.adoc[LangChain4j Web Search]
*** xref:reference/extensions/language.adoc[Language]
-*** xref:reference/extensions/leveldb.adoc[LevelDB]
*** xref:reference/extensions/log.adoc[Log]
*** xref:reference/extensions/lucene.adoc[Lucene]
*** xref:reference/extensions/lumberjack.adoc[Lumberjack]
@@ -290,7 +282,6 @@
*** xref:reference/extensions/qute.adoc[Qute]
*** xref:reference/extensions/rest-openapi.adoc[REST OpenApi]
*** xref:reference/extensions/rss.adoc[RSS]
-*** xref:reference/extensions/reactive-executor.adoc[Reactive Executor]
*** xref:reference/extensions/reactive-streams.adoc[Reactive Streams]
*** xref:reference/extensions/redis.adoc[Redis]
*** xref:reference/extensions/ref.adoc[Ref]
@@ -322,7 +313,6 @@
*** xref:reference/extensions/smooks.adoc[Smooks]
*** xref:reference/extensions/snakeyaml.adoc[SnakeYAML]
*** xref:reference/extensions/solr.adoc[Solr]
-*** xref:reference/extensions/splunk.adoc[Splunk]
*** xref:reference/extensions/splunk-hec.adoc[Splunk HEC]
*** xref:reference/extensions/spring-rabbitmq.adoc[Spring RabbitMQ]
*** xref:reference/extensions/spring-redis.adoc[Spring Redis]
@@ -336,7 +326,6 @@
*** xref:reference/extensions/tarfile.adoc[Tar File]
*** xref:reference/extensions/telegram.adoc[Telegram]
*** xref:reference/extensions/telemetry-dev.adoc[Telemetry Dev]
-*** xref:reference/extensions/threadpoolfactory-vertx.adoc[ThreadPoolFactory Vert.x]
*** xref:reference/extensions/thrift.adoc[Thrift]
*** xref:reference/extensions/tika.adoc[Tika]
*** xref:reference/extensions/timer.adoc[Timer]
diff --git a/docs/modules/ROOT/pages/contributor-guide/build-items.adoc b/docs/modules/ROOT/pages/contributor-guide/build-items.adoc
index f9e7798354..c382d474ef 100644
--- a/docs/modules/ROOT/pages/contributor-guide/build-items.adoc
+++ b/docs/modules/ROOT/pages/contributor-guide/build-items.adoc
@@ -244,15 +244,6 @@ a|https://github.com/apache/camel-quarkus/blob/main/extensions-core/core/deploym
Holds the `org.apache.camel.spi.TypeConverterRegistry` `RuntimeValue`.
a|`RuntimeValue<TypeConverterRegistry> value`
-a|https://github.com/apache/camel-quarkus/blob/main/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CompiledCSimpleExpressionBuildItem.java[`org.apache.camel.quarkus.core.deployment.spi.CompiledCSimpleExpressionBuildItem`,window=_blank]
-
-A `MultiBuildItem` bearing info about a compiled CSimple language expression.
-a|`String sourceCode`
-
-`String className`
-
-`boolean predicate`
-
a|https://github.com/apache/camel-quarkus/blob/main/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/ContainerBeansBuildItem.java[`org.apache.camel.quarkus.core.deployment.spi.ContainerBeansBuildItem`,window=_blank]
Hold a set of beans known to the ArC container.
@@ -286,22 +277,6 @@ _No Javadoc found_
a|`Properties properties`
|===
-== CSimple
-
-[width="100%",cols="50,50",options="header"]
-|===
-| Class name | Attributes
-
-a|https://github.com/apache/camel-quarkus/blob/main/extensions/csimple/deployment/src/main/java/org/apache/camel/quarkus/component/csimple/deployment/CSimpleExpressionSourceBuildItem.java[`org.apache.camel.quarkus.component.csimple.deployment.CSimpleExpressionSourceBuildItem`,window=_blank]
-
-A `MultiBuildItem` bearing info about a CSimple language expression that needs to get compiled.
-a|`String sourceCode`
-
-`String classNameBase`
-
-`boolean predicate`
-|===
-
== DataSonnet
[width="100%",cols="50,50",options="header"]
diff --git a/docs/modules/ROOT/pages/reference/extensions/ai-tool.adoc b/docs/modules/ROOT/pages/reference/extensions/ai-tool.adoc
index cc1bf8a1af..7eafc7ad61 100644
--- a/docs/modules/ROOT/pages/reference/extensions/ai-tool.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/ai-tool.adoc
@@ -46,7 +46,7 @@ endif::[]
[id="extensions-ai-tool-usage"]
== Usage
-The `ai-tool` component is a framework-agnostic consumer endpoint that registers Camel routes as LLM-callable tools in a shared `AiToolRegistry`. Framework-specific extensions (such as `camel-quarkus-langchain4j-tools`, `camel-quarkus-openai`) discover and invoke these tools at runtime.
+The `ai-tool` component is a framework-agnostic consumer endpoint that registers Camel routes as LLM-callable tools in a shared `AiToolRegistry`. Framework-specific extensions (such as `camel-quarkus-langchain4j-agent`, `camel-quarkus-openai`) discover and invoke these tools at runtime.
[id="extensions-ai-tool-usage-defining-a-tool"]
=== Defining a tool
diff --git a/docs/modules/ROOT/pages/reference/extensions/core.adoc b/docs/modules/ROOT/pages/reference/extensions/core.adoc
index 2abeeab68e..aa0344489a 100644
--- a/docs/modules/ROOT/pages/reference/extensions/core.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/core.adoc
@@ -395,12 +395,6 @@ Enable automatic discovery of routes during static initialization.
| `boolean`
| `true`
-a|icon:lock[title=Fixed at build time] [[quarkus-camel-csimple-on-build-time-analysis-failure]]`link:#quarkus-camel-csimple-on-build-time-analysis-failure[quarkus.camel.csimple.on-build-time-analysis-failure]`
-
-What to do if it is not possible to extract CSimple expressions from a route definition at build time.
-| `fail`, `warn`, `ignore`
-| `warn`
-
a|icon:lock[title=Fixed at build time] [[quarkus-camel-trace-enabled]]`link:#quarkus-camel-trace-enabled[quarkus.camel.trace.enabled]`
Enables tracer in your Camel application.
diff --git a/docs/modules/ROOT/pages/reference/extensions/csimple.adoc b/docs/modules/ROOT/pages/reference/extensions/csimple.adoc
deleted file mode 100644
index 3bf950e312..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/csimple.adoc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-csimple"]
-= CSimple
-:linkattrs:
-:cq-artifact-id: camel-quarkus-csimple
-:cq-native-supported: true
-:cq-status: Preview
-:cq-status-deprecation: Preview Deprecated
-:cq-description: Compiled Simple language
-:cq-deprecated: true
-:cq-jvm-since: 1.5.0
-:cq-native-since: 1.5.0
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.5.0## [.badge-key]##Native since##[.badge-supported]##1.5.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-Compiled Simple language
-
-[id="extensions-csimple-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}:languages:csimple-language.adoc[CSimple language]
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-csimple-maven-coordinates"]
-== Maven coordinates
-
-https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-csimple[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
-
-Or add the coordinates to your existing project:
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-csimple</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
-
-[id="extensions-csimple-camel-quarkus-limitations"]
-== Camel Quarkus limitations
-
-CSimple language is supported in all existing DSLs, but be aware that to extract the expressions from the existing route definitions, a dry run is done during the startup in JVM mode or during the build in Native mode which adds some log entries of the following type that you can simply ignore.
-
-[source,text]
-----
-2023-01-19 16:36:31,779 INFO [org.apa.cam.mai.MainSupport] (build-10) Expression Extractor 3.20.1 is starting
-2023-01-19 16:36:32,214 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (build-10) Apache Camel 3.20.1 (Expression Extractor) is starting
-2023-01-19 16:36:32,216 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (build-10) Routes startup (started:0)
-2023-01-19 16:36:32,217 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (build-10) Apache Camel 3.20.1 (Expression Extractor) started in 128ms (build:22ms init:104ms start:2ms)
-2023-01-19 16:36:32,218 INFO [org.apa.cam.mai.MainSupport] (build-10) Waiting until complete: Duration max 1 seconds
-2023-01-19 16:36:33,223 INFO [org.apa.cam.mai.MainSupport] (build-10) Duration max seconds triggering shutdown of the JVM
-2023-01-19 16:36:33,223 INFO [org.apa.cam.mai.MainSupport] (build-10) Expression Extractor 3.20.1 shutdown
-----
-
-The compilation of CSimple scripts happens at build time by default. To be able to discover the scripts in the route definitions,
-those definitions need to get assembled at build time. When extending
-`org.apache.camel.builder.RouteBuilder`, this basically means instantiating your `RouteBuilder`, setting
-a fake `CamelContext` instance on it and calling its `configure()` method. It may fail if your `configure()`
-method attempts to access some resource that is only available at runtime.
-
-You can use the `quarkus.camel.expression.on-build-time-analysis-failure` configuration parameter to decide
-what should happen in such cases. Possible values are `warn` (default), `fail` or `ignore`.
-
-You can also simply disable the expression extraction process by setting the configuration parameter `quarkus.camel.expression.extraction-enabled` to `false`.
-
-If the expression extraction process is disabled or fails, the expressions are then compiled at runtime which also means that it
-can only work in JVM mode moreover the artifact `org.apache.camel:camel-csimple-joor` has to be added to the classpath.
-
-[WARNING]
-====
-CSimple language will not work on Camel Quarkus if used in a `org.apache.camel.builder.LambdaRouteBuilder` or if a `RouteBuilder` depends on dependency injection.
-====
-
-
diff --git a/docs/modules/ROOT/pages/reference/extensions/digitalocean.adoc b/docs/modules/ROOT/pages/reference/extensions/digitalocean.adoc
deleted file mode 100644
index b206771fa3..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/digitalocean.adoc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-digitalocean"]
-= DigitalOcean
-:linkattrs:
-:cq-artifact-id: camel-quarkus-digitalocean
-:cq-native-supported: true
-:cq-status: Stable
-:cq-status-deprecation: Stable Deprecated
-:cq-description: Manage Droplets and resources within the DigitalOcean cloud.
-:cq-deprecated: true
-:cq-jvm-since: 1.1.0
-:cq-native-since: 2.0.0
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.1.0## [.badge-key]##Native since##[.badge-supported]##2.0.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-Manage Droplets and resources within the DigitalOcean cloud.
-
-[id="extensions-digitalocean-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}::digitalocean-component.adoc[DigitalOcean component], URI syntax: `digitalocean:operation`
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-digitalocean-maven-coordinates"]
-== Maven coordinates
-
-https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-digitalocean[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
-
-Or add the coordinates to your existing project:
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-digitalocean</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
-
-[id="extensions-digitalocean-ssl-in-native-mode"]
-== SSL in native mode
-
-This extension auto-enables SSL support in native mode. Hence you do not need to add
-`quarkus.ssl.native=true` to your `application.properties` yourself. See also
-https://quarkus.io/guides/native-and-ssl[Quarkus SSL guide].
diff --git a/docs/modules/ROOT/pages/reference/extensions/hazelcast.adoc b/docs/modules/ROOT/pages/reference/extensions/hazelcast.adoc
index ff432cb4ba..82e6fb0d31 100644
--- a/docs/modules/ROOT/pages/reference/extensions/hazelcast.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/hazelcast.adoc
@@ -1,28 +1,27 @@
// Do not edit directly!
// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
[id="extensions-hazelcast"]
-= Hazelcast Atomic Number
+= Hazelcast
:linkattrs:
:cq-artifact-id: camel-quarkus-hazelcast
:cq-native-supported: true
:cq-status: Stable
-:cq-status-deprecation: Stable Deprecated
-:cq-description: Increment, decrement, set, etc. Hazelcast atomic number (a grid wide number).
-:cq-deprecated: true
+:cq-status-deprecation: Stable
+:cq-description: Perform operations on Hazelcast distributed data structures such as map, multimap, list, set, queue, topic and ringbuffer.
+:cq-deprecated: false
:cq-jvm-since: 1.1.0
:cq-native-since: 1.6.0
ifeval::[{doc-show-badges} == true]
[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.1.0## [.badge-key]##Native since##[.badge-supported]##1.6.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
+[.badge-key]##JVM since##[.badge-supported]##1.1.0## [.badge-key]##Native since##[.badge-supported]##1.6.0##
endif::[]
-Increment, decrement, set, etc. Hazelcast atomic number (a grid wide number).
+Perform operations on Hazelcast distributed data structures such as map, multimap, list, set, queue, topic and ringbuffer.
[id="extensions-hazelcast-whats-inside"]
== What's inside
-* xref:{cq-camel-components}::hazelcast-atomicvalue-component.adoc[Hazelcast Atomic Number component], URI syntax: `hazelcast-atomicvalue:cacheName`
* xref:{cq-camel-components}::hazelcast-instance-component.adoc[Hazelcast Instance component], URI syntax: `hazelcast-instance:cacheName`
* xref:{cq-camel-components}::hazelcast-list-component.adoc[Hazelcast List component], URI syntax: `hazelcast-list:cacheName`
* xref:{cq-camel-components}::hazelcast-map-component.adoc[Hazelcast Map component], URI syntax: `hazelcast-map:cacheName`
diff --git a/docs/modules/ROOT/pages/reference/extensions/headersmap.adoc b/docs/modules/ROOT/pages/reference/extensions/headersmap.adoc
deleted file mode 100644
index 890cf81f3d..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/headersmap.adoc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-headersmap"]
-= Headersmap
-:linkattrs:
-:cq-artifact-id: camel-quarkus-headersmap
-:cq-native-supported: true
-:cq-status: Stable
-:cq-status-deprecation: Stable Deprecated
-:cq-description: Fast case-insensitive headers map implementation
-:cq-deprecated: true
-:cq-jvm-since: 1.2.0
-:cq-native-since: 1.2.0
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.2.0## [.badge-key]##Native since##[.badge-supported]##1.2.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-Fast case-insensitive headers map implementation
-
-[id="extensions-headersmap-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}:others:headersmap.adoc[Headersmap]
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-headersmap-maven-coordinates"]
-== Maven coordinates
-
-https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-headersmap[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
-
-Or add the coordinates to your existing project:
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-headersmap</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
diff --git a/docs/modules/ROOT/pages/reference/extensions/iec60870.adoc b/docs/modules/ROOT/pages/reference/extensions/iec60870.adoc
deleted file mode 100644
index 3a5f28563a..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/iec60870.adoc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-iec60870"]
-= IEC 60870 Client
-:linkattrs:
-:cq-artifact-id: camel-quarkus-iec60870
-:cq-native-supported: false
-:cq-status: Preview
-:cq-status-deprecation: Preview Deprecated
-:cq-description: IEC 60870 supervisory control and data acquisition (SCADA) client using NeoSCADA implementation.
-:cq-deprecated: true
-:cq-jvm-since: 1.1.0
-:cq-native-since: n/a
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.1.0## [.badge-key]##Native##[.badge-unsupported]##unsupported## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-IEC 60870 supervisory control and data acquisition (SCADA) client using NeoSCADA implementation.
-
-[id="extensions-iec60870-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}::iec60870-client-component.adoc[IEC 60870 Client component], URI syntax: `iec60870-client:uriPath`
-* xref:{cq-camel-components}::iec60870-server-component.adoc[IEC 60870 Server component], URI syntax: `iec60870-server:uriPath`
-
-Please refer to the above links for usage and configuration details.
-
-[id="extensions-iec60870-maven-coordinates"]
-== Maven coordinates
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-iec60870</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
diff --git a/docs/modules/ROOT/pages/reference/extensions/irc.adoc b/docs/modules/ROOT/pages/reference/extensions/irc.adoc
deleted file mode 100644
index 5fa24ab969..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/irc.adoc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-irc"]
-= IRC
-:linkattrs:
-:cq-artifact-id: camel-quarkus-irc
-:cq-native-supported: false
-:cq-status: Preview
-:cq-status-deprecation: Preview Deprecated
-:cq-description: Send and receive messages to/from an IRC chat.
-:cq-deprecated: true
-:cq-jvm-since: 1.1.0
-:cq-native-since: n/a
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.1.0## [.badge-key]##Native##[.badge-unsupported]##unsupported## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-Send and receive messages to/from an IRC chat.
-
-[id="extensions-irc-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}::irc-component.adoc[IRC component], URI syntax: `irc:hostname:port`
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-irc-maven-coordinates"]
-== Maven coordinates
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-irc</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
diff --git a/docs/modules/ROOT/pages/reference/extensions/joor.adoc b/docs/modules/ROOT/pages/reference/extensions/joor.adoc
index c227c60710..330c33a12d 100644
--- a/docs/modules/ROOT/pages/reference/extensions/joor.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/joor.adoc
@@ -6,15 +6,15 @@
:cq-artifact-id: camel-quarkus-joor
:cq-native-supported: true
:cq-status: Stable
-:cq-status-deprecation: Stable Deprecated
+:cq-status-deprecation: Stable
:cq-description: Evaluate a jOOR (Java compiled once at runtime) expression language.
-:cq-deprecated: true
+:cq-deprecated: false
:cq-jvm-since: 2.0.0
:cq-native-since: 3.2.0
ifeval::[{doc-show-badges} == true]
[.badges]
-[.badge-key]##JVM since##[.badge-supported]##2.0.0## [.badge-key]##Native since##[.badge-supported]##3.2.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
+[.badge-key]##JVM since##[.badge-supported]##2.0.0## [.badge-key]##Native since##[.badge-supported]##3.2.0##
endif::[]
Evaluate a jOOR (Java compiled once at runtime) expression language.
@@ -23,9 +23,8 @@ Evaluate a jOOR (Java compiled once at runtime) expression language.
== What's inside
* xref:{cq-camel-components}:languages:java-language.adoc[Java language]
-* xref:{cq-camel-components}:languages:joor-language.adoc[jOOR language]
-Please refer to the above links for usage and configuration details.
+Please refer to the above link for usage and configuration details.
[id="extensions-joor-maven-coordinates"]
== Maven coordinates
diff --git a/docs/modules/ROOT/pages/reference/extensions/json-patch.adoc b/docs/modules/ROOT/pages/reference/extensions/json-patch.adoc
deleted file mode 100644
index 39b460cf2f..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/json-patch.adoc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-json-patch"]
-= JsonPatch
-:linkattrs:
-:cq-artifact-id: camel-quarkus-json-patch
-:cq-native-supported: false
-:cq-status: Preview
-:cq-status-deprecation: Preview Deprecated
-:cq-description: Transforms JSON using JSON patch (RFC 6902).
-:cq-deprecated: true
-:cq-jvm-since: 2.7.0
-:cq-native-since: n/a
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##2.7.0## [.badge-key]##Native##[.badge-unsupported]##unsupported## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-Transforms JSON using JSON patch (RFC 6902).
-
-[id="extensions-json-patch-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}::json-patch-component.adoc[JsonPatch component], URI syntax: `json-patch:resourceUri`
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-json-patch-maven-coordinates"]
-== Maven coordinates
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-json-patch</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
diff --git a/docs/modules/ROOT/pages/reference/extensions/jt400.adoc b/docs/modules/ROOT/pages/reference/extensions/jt400.adoc
index 60db880454..5af071ba3e 100644
--- a/docs/modules/ROOT/pages/reference/extensions/jt400.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/jt400.adoc
@@ -22,7 +22,7 @@ Exchanges messages with an IBM i system using data queues, message queues, or pr
[id="extensions-jt400-whats-inside"]
== What's inside
-* xref:{cq-camel-components}::jt400-component.adoc[JT400 component], URI syntax: `jt400:userID:password@systemName/QSYS.LIB/objectPath.type`
+* xref:{cq-camel-components}::jt400-component.adoc[JT400 component], URI syntax: `jt400:userID:password@systemName/objectPath`
Please refer to the above link for usage and configuration details.
diff --git a/docs/modules/ROOT/pages/reference/extensions/langchain4j-ingest.adoc b/docs/modules/ROOT/pages/reference/extensions/langchain4j-ingest.adoc
index 8c5cf20904..6a9adaa8e2 100644
--- a/docs/modules/ROOT/pages/reference/extensions/langchain4j-ingest.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/langchain4j-ingest.adoc
@@ -7,7 +7,7 @@
:cq-native-supported: true
:cq-status: Experimental
:cq-status-deprecation: Experimental
-:cq-description: Declarative AI document ingestion: point a knowledge base at a folder via configuration; splitting, embedding and storing are handled under the hood
+:cq-description: Ingest documents into a LangChain4j EmbeddingStore: split, embed and store the message body.
:cq-deprecated: false
:cq-jvm-since: 3.39.0
:cq-native-since: 3.39.0
@@ -19,6 +19,13 @@ endif::[]
Ingest documents into a LangChain4j EmbeddingStore: split, embed and store the message body.
+[id="extensions-langchain4j-ingest-whats-inside"]
+== What's inside
+
+* xref:{cq-camel-components}::langchain4j-ingest-component.adoc[LangChain4j Ingest component], URI syntax: `langchain4j-ingest:pipelineName`
+
+Please refer to the above link for usage and configuration details.
+
[id="extensions-langchain4j-ingest-maven-coordinates"]
== Maven coordinates
@@ -181,7 +188,7 @@ The method runs once at startup; it must return `IngestPipeline`, take no parame
A component missing from the classpath fails at startup with an error naming the extension artifact that provides it — the DSL compiles regardless, since its factories all ship in one artifact.
Ingestion needs a stable id per document, and where it lives is the consumer's business: `documentId` names the header — the record key `CamelKafkaKey` above, `CamelAwsS3Key` for S3 — or gives a simple-language expression.
-Without it, the pipeline expects the `CamelIngestDocumentId` header and fails the exchange when it is absent.
+Without it, the pipeline expects the `CamelLangChain4jIngestDocumentId` header — the `camel-langchain4j-ingest` component's convention; the 3.39 name `CamelIngestDocumentId` is still read as a fallback, see the migration guide — and fails the exchange when both are absent.
Mind each component's own defaults, too: the `aws2-s3` consumer *deletes objects after reading them* unless `deleteAfterRead(false)` is set — a knowledge base reads its source, it does not consume it.
After such a pipeline ingests a document, the exchange body is replaced with the `IngestResult`, so a request-reply caller receives the outcome of its call.
@@ -232,8 +239,12 @@ Note that the import order is paramount when using maven `dependencyManagement`.
As such, one might need to import the `langchain4j-bom` before other related Camel and Quarkus BOMs.
=== Quarkus LangChain4j support
+WARNING: At present, this extension is neither tested with nor intended to be used in conjunction with any Quarkus LangChain4j extensions.
+Consequently, both JVM and native modes may exhibit unexpected behaviour or fail to function correctly in such configurations.
-This extension is designed and tested to work together with the https://docs.quarkiverse.io/quarkus-langchain4j/dev/index.html[Quarkus LangChain4j] extensions. The `EmbeddingStore` and `EmbeddingModel` beans a pipeline writes through are ordinary CDI beans shared by both stacks — including stores declared through Quarkus LangChain4j configuration — and with the RAG augmentor bridge an `@RegisterAiService` interface answers from the store a pipeline filled, without glue code. The integrat [...]
+The `EmbeddingStore` and `EmbeddingModel` beans used by an ingestion pipeline are regular CDI beans, so they can be shared with Quarkus LangChain4j. This includes embedding stores configured through Quarkus LangChain4j.
+
+Combined with the xref:reference/extensions/langchain4j-embeddingstore.adoc#extensions-langchain4j-embeddingstore-usage-retrieval-augmentors-for-registeraiservice[RAG augmentor bridge], an `@RegisterAiService` interface can retrieve content from the embedding store populated by a pipeline.
[id="extensions-langchain4j-ingest-additional-camel-quarkus-configuration"]
@@ -264,7 +275,7 @@ structure-preserving markdown through a Docling Serve instance (configure it wit
value needs its extension on the classpath: `camel-quarkus-tika` or
`camel-quarkus-docling`.
| `string`
-|
+|
a|icon:lock[title=Fixed at build time] [[quarkus-camel-langchain4j-ingest-pipeline-name-embedding-store]]`link:#quarkus-camel-langchain4j-ingest-pipeline-name-embedding-store[quarkus.camel.langchain4j.ingest."pipeline-name".embedding-store]`
@@ -318,7 +329,7 @@ Name of the `DocumentSplitter` bean replacing the default recursive splitting;
an application may hold unrelated splitters. Segments returned without the identity
metadata are re-stamped, so a custom splitter cannot break citation.
| `string`
-|
+|
a| [[quarkus-camel-langchain4j-ingest-pipeline-name-enabled]]`link:#quarkus-camel-langchain4j-ingest-pipeline-name-enabled[quarkus.camel.langchain4j.ingest."pipeline-name".enabled]`
@@ -366,7 +377,8 @@ expression in the `+$simple{...}+` form — MicroProfile Config passes it throug
untouched, while a `+${...}+` in a properties file would be consumed as a config
expansion before Camel ever saw it. When not set, a pipeline reading a directory
uses the file name, and one consuming from a component uses the
-`CamelIngestDocumentId` header.
+`CamelLangChain4jIngestDocumentId` header (the deprecated 3.39 name
+`CamelIngestDocumentId` is still read as a fallback).
| `string`
|
|===
diff --git a/docs/modules/ROOT/pages/reference/extensions/langchain4j-tools.adoc b/docs/modules/ROOT/pages/reference/extensions/langchain4j-tools.adoc
deleted file mode 100644
index 9c6818fdbf..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/langchain4j-tools.adoc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-langchain4j-tools"]
-= LangChain4j Tools
-:linkattrs:
-:cq-artifact-id: camel-quarkus-langchain4j-tools
-:cq-native-supported: true
-:cq-status: Preview
-:cq-status-deprecation: Preview Deprecated
-:cq-description: LangChain4j Tools and Function Calling Features
-:cq-deprecated: true
-:cq-jvm-since: 3.15.0
-:cq-native-since: 3.24.0
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##3.15.0## [.badge-key]##Native since##[.badge-supported]##3.24.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-LangChain4j Tools and Function Calling Features
-
-[id="extensions-langchain4j-tools-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}::langchain4j-tools-component.adoc[LangChain4j Tools component], URI syntax: `langchain4j-tools:toolId`
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-langchain4j-tools-maven-coordinates"]
-== Maven coordinates
-
-https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-langchain4j-tools[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
-
-Or add the coordinates to your existing project:
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-langchain4j-tools</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
-
-[id="extensions-langchain4j-tools-quarkus-langchain4j-bom"]
-== LangChain4j usage
-
-=== Dependency management
-
-In order to ensure alignment across all Quarkus and LangChain4j related dependencies, it is recommended to import the LangChain4j BOM as below:
-[source,xml,subs=attributes+]
-----
-<dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>dev.langchain4j</groupId>
- <artifactId>langchain4j-bom</artifactId>
- <version>{langchain4j-version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- ...
-</dependencyManagement>
-----
-
-Note that the import order is paramount when using maven `dependencyManagement`.
-As such, one might need to import the `langchain4j-bom` before other related Camel and Quarkus BOMs.
-
-=== Quarkus LangChain4j support
-WARNING: At present, this extension is neither tested with nor intended to be used in conjunction with any Quarkus LangChain4j extensions.
-Consequently, both JVM and native modes may exhibit unexpected behaviour or fail to function correctly in such configurations.
diff --git a/docs/modules/ROOT/pages/reference/extensions/leveldb.adoc b/docs/modules/ROOT/pages/reference/extensions/leveldb.adoc
deleted file mode 100644
index 4f39509b61..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/leveldb.adoc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-leveldb"]
-= LevelDB
-:linkattrs:
-:cq-artifact-id: camel-quarkus-leveldb
-:cq-native-supported: true
-:cq-status: Stable
-:cq-status-deprecation: Stable Deprecated
-:cq-description: Using LevelDB as persistent EIP store
-:cq-deprecated: true
-:cq-jvm-since: 1.2.0
-:cq-native-since: 1.2.0
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.2.0## [.badge-key]##Native since##[.badge-supported]##1.2.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-Using LevelDB as persistent EIP store
-
-[id="extensions-leveldb-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}:others:leveldb.adoc[LevelDB]
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-leveldb-maven-coordinates"]
-== Maven coordinates
-
-https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-leveldb[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
-
-Or add the coordinates to your existing project:
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-leveldb</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
-
-[id="extensions-leveldb-camel-quarkus-limitations"]
-== Camel Quarkus limitations
-
-In native mode the extension uses a port of LevelDB written in Java (https://github.com/dain/leveldb#leveldb-in-java[documentation]),
-which is within 10% of the performance of the C++ original. Please upvote https://github.com/apache/camel-quarkus/issues/1911[this issue]
-if you do not like the present state.
-
-Serialization is https://github.com/oracle/graal/issues/460[not supported] on GraalVM. Extension has to use serialization based
-on Jackson. Aggregation repository in native has to be constructed in one of the following ways:
-
-* Use class `QuarkusLevelDBAggregationRepository` instead of `LevelDBAggregationRepository`.
-* Configure jackson serializer on `LevelDBAggregationRepository` by calling `repo.setSerializer(new JacksonLevelDBSerializer());`
-
-Jackson serializer has limitation towards binary content. If payload object contains binary data (does not concern payloads which are completely binary), Jackson serialization and deserialization won't work correctly.
-To avoid this, define your own jackson serializer/deserializer via `Module` and provide it to the aggregation repository
-(you can use for example the constructor of `QuarkusLevelDBAggregationRepository`).
-
-
diff --git a/docs/modules/ROOT/pages/reference/extensions/mcp-server.adoc b/docs/modules/ROOT/pages/reference/extensions/mcp-server.adoc
index 080044d97d..21935ece3e 100644
--- a/docs/modules/ROOT/pages/reference/extensions/mcp-server.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/mcp-server.adoc
@@ -7,7 +7,7 @@
:cq-native-supported: true
:cq-status: Preview
:cq-status-deprecation: Preview
-:cq-description: Expose ai-tool routes as MCP tools over streamable HTTP
+:cq-description: Expose ai-tool routes as MCP tools and ai-resource routes as MCP resources over streamable HTTP
:cq-deprecated: false
:cq-jvm-since: 3.39.0
:cq-native-since: 3.39.0
diff --git a/docs/modules/ROOT/pages/reference/extensions/minio.adoc b/docs/modules/ROOT/pages/reference/extensions/minio.adoc
index 97f4700dcc..010b9cc9e8 100644
--- a/docs/modules/ROOT/pages/reference/extensions/minio.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/minio.adoc
@@ -6,15 +6,15 @@
:cq-artifact-id: camel-quarkus-minio
:cq-native-supported: true
:cq-status: Stable
-:cq-status-deprecation: Stable
+:cq-status-deprecation: Stable Deprecated
:cq-description: Store and retrieve objects from Minio Storage Service using Minio SDK.
-:cq-deprecated: false
+:cq-deprecated: true
:cq-jvm-since: 1.5.0
:cq-native-since: 1.6.0
ifeval::[{doc-show-badges} == true]
[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.5.0## [.badge-key]##Native since##[.badge-supported]##1.6.0##
+[.badge-key]##JVM since##[.badge-supported]##1.5.0## [.badge-key]##Native since##[.badge-supported]##1.6.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
endif::[]
Store and retrieve objects from Minio Storage Service using Minio SDK.
diff --git a/docs/modules/ROOT/pages/reference/extensions/openai.adoc b/docs/modules/ROOT/pages/reference/extensions/openai.adoc
index 6f68832dd6..28d11d6ca3 100644
--- a/docs/modules/ROOT/pages/reference/extensions/openai.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/openai.adoc
@@ -7,7 +7,7 @@
:cq-native-supported: true
:cq-status: Stable
:cq-status-deprecation: Stable
-:cq-description: OpenAI endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech.
+:cq-description: LLM endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech using OpenAI-compatible APIs. The openai scheme is a supported alias.
:cq-deprecated: false
:cq-jvm-since: 3.32.0
:cq-native-since: 3.32.0
@@ -17,14 +17,15 @@ ifeval::[{doc-show-badges} == true]
[.badge-key]##JVM since##[.badge-supported]##3.32.0## [.badge-key]##Native since##[.badge-supported]##3.32.0##
endif::[]
-OpenAI endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech.
+LLM endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech using OpenAI-compatible APIs. The openai scheme is a supported alias.
[id="extensions-openai-whats-inside"]
== What's inside
+* xref:{cq-camel-components}::openai-component.adoc[LLM component], URI syntax: `llm:operation`
* xref:{cq-camel-components}::openai-component.adoc[OpenAI component], URI syntax: `openai:operation`
-Please refer to the above link for usage and configuration details.
+Please refer to the above links for usage and configuration details.
[id="extensions-openai-maven-coordinates"]
== Maven coordinates
diff --git a/docs/modules/ROOT/pages/reference/extensions/reactive-executor.adoc b/docs/modules/ROOT/pages/reference/extensions/reactive-executor.adoc
deleted file mode 100644
index 08f66362e6..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/reactive-executor.adoc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-reactive-executor"]
-= Reactive Executor
-:page-aliases: extensions/reactive-executor.adoc
-:linkattrs:
-:cq-artifact-id: camel-quarkus-reactive-executor
-:cq-native-supported: true
-:cq-status: Stable
-:cq-status-deprecation: Stable Deprecated
-:cq-description: Reactive Executor for camel-core using Vert.x
-:cq-deprecated: true
-:cq-jvm-since: 0.3.0
-:cq-native-since: 0.3.0
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##0.3.0## [.badge-key]##Native since##[.badge-supported]##0.3.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-Reactive Executor for camel-core using Vert.x
-
-[id="extensions-reactive-executor-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}:others:reactive-executor-vertx.adoc[Reactive Executor Vert.x]
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-reactive-executor-maven-coordinates"]
-== Maven coordinates
-
-https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-reactive-executor[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
-
-Or add the coordinates to your existing project:
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-reactive-executor</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
diff --git a/docs/modules/ROOT/pages/reference/extensions/splunk.adoc b/docs/modules/ROOT/pages/reference/extensions/splunk.adoc
deleted file mode 100644
index 0a2dfade37..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/splunk.adoc
+++ /dev/null
@@ -1,52 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-splunk"]
-= Splunk
-:linkattrs:
-:cq-artifact-id: camel-quarkus-splunk
-:cq-native-supported: true
-:cq-status: Stable
-:cq-status-deprecation: Stable Deprecated
-:cq-description: Publish or search for events in Splunk.
-:cq-deprecated: true
-:cq-jvm-since: 1.8.0
-:cq-native-since: 1.8.0
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.8.0## [.badge-key]##Native since##[.badge-supported]##1.8.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-Publish or search for events in Splunk.
-
-[id="extensions-splunk-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}::splunk-component.adoc[Splunk component], URI syntax: `splunk:name`
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-splunk-maven-coordinates"]
-== Maven coordinates
-
-https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-splunk[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
-
-Or add the coordinates to your existing project:
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-splunk</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
-
-[id="extensions-splunk-ssl-in-native-mode"]
-== SSL in native mode
-
-This extension auto-enables SSL support in native mode. Hence you do not need to add
-`quarkus.ssl.native=true` to your `application.properties` yourself. See also
-https://quarkus.io/guides/native-and-ssl[Quarkus SSL guide].
diff --git a/docs/modules/ROOT/pages/reference/extensions/threadpoolfactory-vertx.adoc b/docs/modules/ROOT/pages/reference/extensions/threadpoolfactory-vertx.adoc
deleted file mode 100644
index 1d58c50d93..0000000000
--- a/docs/modules/ROOT/pages/reference/extensions/threadpoolfactory-vertx.adoc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Do not edit directly!
-// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
-[id="extensions-threadpoolfactory-vertx"]
-= ThreadPoolFactory Vert.x
-:page-aliases: extensions/threadpoolfactory-vertx.adoc
-:linkattrs:
-:cq-artifact-id: camel-quarkus-threadpoolfactory-vertx
-:cq-native-supported: true
-:cq-status: Stable
-:cq-status-deprecation: Stable Deprecated
-:cq-description: ThreadPoolFactory for camel-core using Vert.x
-:cq-deprecated: true
-:cq-jvm-since: 1.0.0
-:cq-native-since: 1.0.0
-
-ifeval::[{doc-show-badges} == true]
-[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.0.0## [.badge-key]##Native since##[.badge-supported]##1.0.0## [.badge-key]##⚠️##[.badge-unsupported]##Deprecated##
-endif::[]
-
-ThreadPoolFactory for camel-core using Vert.x
-
-[id="extensions-threadpoolfactory-vertx-whats-inside"]
-== What's inside
-
-* xref:{cq-camel-components}:others:threadpoolfactory-vertx.adoc[ThreadPoolFactory Vert.x]
-
-Please refer to the above link for usage and configuration details.
-
-[id="extensions-threadpoolfactory-vertx-maven-coordinates"]
-== Maven coordinates
-
-https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-threadpoolfactory-vertx[Create a new project with this extension on {link-quarkus-code-generator}, window="_blank"]
-
-Or add the coordinates to your existing project:
-
-[source,xml]
-----
-<dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-threadpoolfactory-vertx</artifactId>
-</dependency>
-----
-ifeval::[{doc-show-user-guide-link} == true]
-Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
-endif::[]
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
index 5e535cfbd8..c92025393a 100644
--- a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
+++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
@@ -144,12 +144,6 @@ class CamelProcessor {
void coreServiceFilter(BuildProducer<CamelServiceFilterBuildItem> filterBuildItems) {
filterBuildItems.produce(
new CamelServiceFilterBuildItem(CamelServiceFilter.forService("properties-component-factory")));
-
- // The reactive executor is programmatically configured by an extension or
- // a default implementation is provided by this processor thus we can safely
- // prevent loading of this service.
- filterBuildItems.produce(
- new CamelServiceFilterBuildItem(CamelServiceFilter.forService("reactive-executor")));
}
@BuildStep
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CompiledCSimpleExpressionBuildItem.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CompiledCSimpleExpressionBuildItem.java
deleted file mode 100644
index e81139ccee..0000000000
--- a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CompiledCSimpleExpressionBuildItem.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.quarkus.core.deployment.spi;
-
-import io.quarkus.builder.item.MultiBuildItem;
-
-/**
- * A {@link MultiBuildItem} bearing info about a compiled CSimple language expression.
- */
-public final class CompiledCSimpleExpressionBuildItem extends MultiBuildItem {
-
- private final String sourceCode;
- private final String className;
- private final boolean predicate;
-
- public CompiledCSimpleExpressionBuildItem(String sourceCode, boolean predicate, String className) {
- this.sourceCode = sourceCode;
- this.predicate = predicate;
- this.className = className;
- }
-
- /**
- * @return the source code out which the class returned by {@link #getClassName()} was compiled
- */
- public String getSourceCode() {
- return sourceCode;
- }
-
- /**
- * @return a fully qualified class name compiled from the source code returned by {@link #getSourceCode()}
- */
- public String getClassName() {
- return className;
- }
-
- /**
- * @return {@code true} if the expression is a predicate; {@code false} otherwise
- */
- public boolean isPredicate() {
- return predicate;
- }
-
-}
diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
index f4055c19c1..2fa9278aa6 100644
--- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelConfig.java
@@ -62,14 +62,6 @@ public interface CamelConfig {
@WithName("native")
NativeConfig native_();
- /**
- * Build time configuration options for the Camel CSimple language.
- *
- * @asciidoclet
- */
- @Deprecated(forRemoval = true)
- CSimpleConfig csimple();
-
/**
* Build time configuration options for the extraction of Camel expressions.
*
@@ -387,20 +379,6 @@ public interface CamelConfig {
boolean transformers();
}
- /**
- * @deprecated use {@link ExpressionConfig} instead
- */
- @Deprecated(forRemoval = true)
- interface CSimpleConfig {
- /**
- * What to do if it is not possible to extract CSimple expressions from a route definition at build time.
- *
- * @asciidoclet
- */
- @WithDefault("warn")
- FailureRemedy onBuildTimeAnalysisFailure();
- }
-
interface ExpressionConfig {
/**
* What to do if it is not possible to extract expressions from a route definition at build time.
diff --git a/extensions-core/pom.xml b/extensions-core/pom.xml
index 1b0a3ae5d0..207fa324e3 100644
--- a/extensions-core/pom.xml
+++ b/extensions-core/pom.xml
@@ -35,8 +35,6 @@
<modules>
<module>core</module>
<module>http-common</module>
- <module>reactive-executor</module>
- <module>threadpoolfactory-vertx</module>
<module>xml-io-dsl</module>
<module>xml-jaxb</module>
<module>xml-jaxp</module>
diff --git a/extensions-core/reactive-executor/deployment/pom.xml b/extensions-core/reactive-executor/deployment/pom.xml
deleted file mode 100644
index 19e29e6cfc..0000000000
--- a/extensions-core/reactive-executor/deployment/pom.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-reactive-executor-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-reactive-executor-deployment</artifactId>
- <name>Camel Quarkus :: Core :: Reactive Executor :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-reactive-executor</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-vertx-deployment</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/BuildProcessor.java b/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/BuildProcessor.java
deleted file mode 100644
index 12002969d2..0000000000
--- a/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/BuildProcessor.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.quarkus.reactive.executor.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
-import io.quarkus.vertx.deployment.VertxBuildItem;
-import org.apache.camel.quarkus.core.deployment.spi.RuntimeCamelContextCustomizerBuildItem;
-import org.apache.camel.quarkus.reactive.executor.ReactiveExecutorRecorder;
-
-public class BuildProcessor {
- @Record(value = ExecutionTime.RUNTIME_INIT, optional = true)
- @BuildStep
- RuntimeCamelContextCustomizerBuildItem reactiveExecutorCustomizer(ReactiveExecutorRecorder recorder, VertxBuildItem vertx) {
- return new RuntimeCamelContextCustomizerBuildItem(recorder.createReactiveExecutorCustomizer(vertx.getVertx()));
- }
-}
diff --git a/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/Feature.java b/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/Feature.java
deleted file mode 100644
index ae24845dac..0000000000
--- a/extensions-core/reactive-executor/deployment/src/main/java/org/apache/camel/quarkus/reactive/executor/deployment/Feature.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.quarkus.reactive.executor.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-
-public class Feature {
- private static final String FEATURE = "camel-reactive-executor";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-}
diff --git a/extensions-core/reactive-executor/pom.xml b/extensions-core/reactive-executor/pom.xml
deleted file mode 100644
index 11e34aae8b..0000000000
--- a/extensions-core/reactive-executor/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions-core</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>camel-quarkus-reactive-executor-parent</artifactId>
- <name>Camel Quarkus :: Core :: Reactive Executor</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-
-</project>
diff --git a/extensions-core/reactive-executor/runtime/pom.xml b/extensions-core/reactive-executor/runtime/pom.xml
deleted file mode 100644
index 6c4135e1d4..0000000000
--- a/extensions-core/reactive-executor/runtime/pom.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-reactive-executor-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-reactive-executor</artifactId>
- <name>Camel Quarkus :: Core :: Reactive Executor :: Runtime</name>
- <description>Reactive Executor for camel-core using Vert.x</description>
-
- <properties>
- <camel.quarkus.jvmSince>0.3.0</camel.quarkus.jvmSince>
- <camel.quarkus.nativeSince>0.3.0</camel.quarkus.nativeSince>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
-
- <!-- camel -->
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-reactive-executor-vertx</artifactId>
- </dependency>
-
- <!-- quarkus -->
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-vertx</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/extensions-core/reactive-executor/runtime/src/main/java/org/apache/camel/quarkus/reactive/executor/ReactiveExecutorRecorder.java b/extensions-core/reactive-executor/runtime/src/main/java/org/apache/camel/quarkus/reactive/executor/ReactiveExecutorRecorder.java
deleted file mode 100644
index 27a2db77c8..0000000000
--- a/extensions-core/reactive-executor/runtime/src/main/java/org/apache/camel/quarkus/reactive/executor/ReactiveExecutorRecorder.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.quarkus.reactive.executor;
-
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import io.vertx.core.Vertx;
-import org.apache.camel.CamelContext;
-import org.apache.camel.reactive.vertx.VertXReactiveExecutor;
-import org.apache.camel.spi.CamelContextCustomizer;
-
-@Recorder
-public class ReactiveExecutorRecorder {
- public RuntimeValue<CamelContextCustomizer> createReactiveExecutorCustomizer(RuntimeValue<Vertx> vertx) {
- return new RuntimeValue<>(new CamelContextCustomizer() {
- @Override
- public void configure(CamelContext context) {
- VertXReactiveExecutor executor = new VertXReactiveExecutor();
- executor.setVertx(vertx.getValue());
-
- context.getCamelContextExtension().setReactiveExecutor(executor);
- }
- });
- }
-}
diff --git a/extensions-core/reactive-executor/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions-core/reactive-executor/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 4080b83138..0000000000
--- a/extensions-core/reactive-executor/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel Reactive Executor"
-description: "Reactive Executor for camel-core using Vert.x"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/reactive-executor.html"
- categories:
- - "integration"
- status: "stable"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions-core/threadpoolfactory-vertx/deployment/pom.xml b/extensions-core/threadpoolfactory-vertx/deployment/pom.xml
deleted file mode 100644
index 2bee17dcf8..0000000000
--- a/extensions-core/threadpoolfactory-vertx/deployment/pom.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-threadpoolfactory-vertx-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-threadpoolfactory-vertx-deployment</artifactId>
- <name>Camel Quarkus :: ThreadPoolFactory Vert.x :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-threadpoolfactory-vertx</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-vertx-deployment</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions-core/threadpoolfactory-vertx/deployment/src/main/java/org/apache/camel/quarkus/component/threadpoolfactory/vertx/deployment/ThreadpoolfactoryVertxProcessor.java b/extensions-core/threadpoolfactory-vertx/deployment/src/main/java/org/apache/camel/quarkus/component/threadpoolfactory/vertx/deployment/ThreadpoolfactoryVertxProcessor.java
deleted file mode 100644
index 669245d1a0..0000000000
--- a/extensions-core/threadpoolfactory-vertx/deployment/src/main/java/org/apache/camel/quarkus/component/threadpoolfactory/vertx/deployment/ThreadpoolfactoryVertxProcessor.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.quarkus.component.threadpoolfactory.vertx.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.vertx.deployment.VertxBuildItem;
-import org.apache.camel.quarkus.component.threadpoolfactory.vertx.ThreadPoolFactoryVertxRecorder;
-import org.apache.camel.quarkus.core.deployment.spi.RuntimeCamelContextCustomizerBuildItem;
-
-class ThreadpoolfactoryVertxProcessor {
-
- private static final String FEATURE = "camel-threadpoolfactory-vertx";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- @Record(value = ExecutionTime.RUNTIME_INIT, optional = true)
- @BuildStep
- public RuntimeCamelContextCustomizerBuildItem threadPoolFactoryCustomizer(ThreadPoolFactoryVertxRecorder recorder,
- VertxBuildItem vertx) {
- return new RuntimeCamelContextCustomizerBuildItem(recorder.createThreadPoolFactoryCustomizer(vertx.getVertx()));
- }
-}
diff --git a/extensions-core/threadpoolfactory-vertx/pom.xml b/extensions-core/threadpoolfactory-vertx/pom.xml
deleted file mode 100644
index 6c72ff2d96..0000000000
--- a/extensions-core/threadpoolfactory-vertx/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions-core</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-threadpoolfactory-vertx-parent</artifactId>
- <name>Camel Quarkus :: ThreadPoolFactory Vert.x</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions-core/threadpoolfactory-vertx/runtime/pom.xml b/extensions-core/threadpoolfactory-vertx/runtime/pom.xml
deleted file mode 100644
index add03883c4..0000000000
--- a/extensions-core/threadpoolfactory-vertx/runtime/pom.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-threadpoolfactory-vertx-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-threadpoolfactory-vertx</artifactId>
- <name>Camel Quarkus :: ThreadPoolFactory Vert.x :: Runtime</name>
- <description>ThreadPoolFactory for camel-core using Vert.x</description>
-
- <properties>
- <camel.quarkus.jvmSince>1.0.0</camel.quarkus.jvmSince>
- <camel.quarkus.nativeSince>1.0.0</camel.quarkus.nativeSince>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-threadpoolfactory-vertx</artifactId>
- </dependency>
-
- <!-- quarkus -->
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-vertx</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/extensions-core/threadpoolfactory-vertx/runtime/src/main/java/org/apache/camel/quarkus/component/threadpoolfactory/vertx/ThreadPoolFactoryVertxRecorder.java b/extensions-core/threadpoolfactory-vertx/runtime/src/main/java/org/apache/camel/quarkus/component/threadpoolfactory/vertx/ThreadPoolFactoryVertxRecorder.java
deleted file mode 100644
index 434ba1e0ea..0000000000
--- a/extensions-core/threadpoolfactory-vertx/runtime/src/main/java/org/apache/camel/quarkus/component/threadpoolfactory/vertx/ThreadPoolFactoryVertxRecorder.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.quarkus.component.threadpoolfactory.vertx;
-
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import io.vertx.core.Vertx;
-import org.apache.camel.CamelContext;
-import org.apache.camel.reactive.vertx.VertXThreadPoolFactory;
-import org.apache.camel.spi.CamelContextCustomizer;
-
-@Recorder
-public class ThreadPoolFactoryVertxRecorder {
- public RuntimeValue<CamelContextCustomizer> createThreadPoolFactoryCustomizer(RuntimeValue<Vertx> vertx) {
- return new RuntimeValue<>(new CamelContextCustomizer() {
- @Override
- public void configure(CamelContext context) {
- VertXThreadPoolFactory threadPoolFactory = new VertXThreadPoolFactory();
- threadPoolFactory.setVertx(vertx.getValue());
-
- context.getExecutorServiceManager().setThreadPoolFactory(threadPoolFactory);
- }
- });
- }
-}
diff --git a/extensions-core/threadpoolfactory-vertx/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions-core/threadpoolfactory-vertx/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 10623057c9..0000000000
--- a/extensions-core/threadpoolfactory-vertx/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel ThreadPoolFactory Vert.x"
-description: "ThreadPoolFactory for camel-core using Vert.x"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/threadpoolfactory-vertx.html"
- categories:
- - "integration"
- status: "deprecated"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions-jvm/console/deployment/src/test/java/org/apache/camel/quarkus/component/console/ConsoleEnabledWithDevProfileTest.java b/extensions-jvm/console/deployment/src/test/java/org/apache/camel/quarkus/component/console/ConsoleEnabledWithDevProfileTest.java
index 99deb1374a..dcf16cbd1c 100644
--- a/extensions-jvm/console/deployment/src/test/java/org/apache/camel/quarkus/component/console/ConsoleEnabledWithDevProfileTest.java
+++ b/extensions-jvm/console/deployment/src/test/java/org/apache/camel/quarkus/component/console/ConsoleEnabledWithDevProfileTest.java
@@ -20,6 +20,7 @@ import io.quarkus.test.QuarkusExtensionTest;
import jakarta.inject.Inject;
import org.apache.camel.CamelContext;
import org.apache.camel.console.DevConsoleRegistry;
+import org.apache.camel.impl.console.PropertiesDevConsole;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -43,8 +44,8 @@ class ConsoleEnabledWithDevProfileTest {
}
@Test
- void propertiesConsoleIsQuarkusOverride() {
+ void propertiesConsoleIsCamelDefault() {
DevConsoleRegistry registry = context.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class);
- assertTrue(registry.getConsole("properties").get() instanceof QuarkusPropertiesDevConsole);
+ assertTrue(registry.getConsole("properties").get() instanceof PropertiesDevConsole);
}
}
diff --git a/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/CamelConsoleRecorder.java b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/CamelConsoleRecorder.java
index 8c9f86ac09..42c61b9175 100644
--- a/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/CamelConsoleRecorder.java
+++ b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/CamelConsoleRecorder.java
@@ -53,7 +53,6 @@ public class CamelConsoleRecorder {
DevConsoleRegistry registry = camelContextRuntimeValue.getValue()
.getCamelContextExtension()
.getContextPlugin(DevConsoleRegistry.class);
- registry.register(new QuarkusPropertiesDevConsole());
registry.loadDevConsoles();
}
diff --git a/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusPropertiesDevConsole.java b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusPropertiesDevConsole.java
deleted file mode 100644
index 43a79648ea..0000000000
--- a/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusPropertiesDevConsole.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.quarkus.component.console;
-
-import java.util.Map;
-
-import org.apache.camel.impl.console.PropertiesDevConsole;
-import org.apache.camel.util.json.JsonArray;
-import org.apache.camel.util.json.JsonObject;
-
-/**
- * Temporary override of the Camel {@link PropertiesDevConsole} that filters out entries originating from
- * {@code CamelMicroProfilePropertiesSource}. Those entries duplicate the application properties that Quarkus already
- * provides through the {@code RuntimePropertiesProvider} SPI and would otherwise appear twice in the console output.
- */
-public class QuarkusPropertiesDevConsole extends PropertiesDevConsole {
-
- private static final String MICRO_PROFILE_SOURCE = "CamelMicroProfilePropertiesSource";
-
- @Override
- protected JsonObject doCallJson(Map<String, Object> options) {
- JsonObject root = super.doCallJson(options);
- Object props = root.get("properties");
- if (props instanceof JsonArray arr) {
- arr.removeIf(entry -> entry instanceof JsonObject obj
- && obj.get("location") instanceof String loc
- && loc.startsWith(MICRO_PROFILE_SOURCE));
- }
- return root;
- }
-
- @Override
- protected String doCallText(Map<String, Object> options) {
- StringBuilder filtered = new StringBuilder();
- for (String line : super.doCallText(options).split("\n")) {
- if (!line.contains(MICRO_PROFILE_SOURCE)) {
- filtered.append(line).append('\n');
- }
- }
- return filtered.toString();
- }
-}
diff --git a/extensions-jvm/iec60870/deployment/pom.xml b/extensions-jvm/iec60870/deployment/pom.xml
deleted file mode 100644
index 3207ce6731..0000000000
--- a/extensions-jvm/iec60870/deployment/pom.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-iec60870-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-iec60870-deployment</artifactId>
- <name>Camel Quarkus :: IEC 60870 Client :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-iec60870</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions-jvm/iec60870/deployment/src/main/java/org/apache/camel/quarkus/component/iec60870/deployment/Iec60870Processor.java b/extensions-jvm/iec60870/deployment/src/main/java/org/apache/camel/quarkus/component/iec60870/deployment/Iec60870Processor.java
deleted file mode 100644
index 20c4e718af..0000000000
--- a/extensions-jvm/iec60870/deployment/src/main/java/org/apache/camel/quarkus/component/iec60870/deployment/Iec60870Processor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.quarkus.component.iec60870.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
-import org.jboss.logging.Logger;
-
-class Iec60870Processor {
-
- private static final Logger LOG = Logger.getLogger(Iec60870Processor.class);
- private static final String FEATURE = "camel-iec60870";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- /**
- * Remove this once this extension starts supporting the native mode.
- */
- @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
- @Record(value = ExecutionTime.RUNTIME_INIT)
- void warnJvmInNative(JvmOnlyRecorder recorder) {
- JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
- recorder.warnJvmInNative(FEATURE); // warn at runtime
- }
-}
diff --git a/extensions-jvm/iec60870/pom.xml b/extensions-jvm/iec60870/pom.xml
deleted file mode 100644
index c4d458d87c..0000000000
--- a/extensions-jvm/iec60870/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions-jvm</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-iec60870-parent</artifactId>
- <name>Camel Quarkus :: IEC 60870 Client</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions-jvm/iec60870/runtime/pom.xml b/extensions-jvm/iec60870/runtime/pom.xml
deleted file mode 100644
index 0f6d2e8a96..0000000000
--- a/extensions-jvm/iec60870/runtime/pom.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-iec60870-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-iec60870</artifactId>
- <name>Camel Quarkus :: IEC 60870 Client :: Runtime</name>
- <description>IEC 60870 supervisory control and data acquisition (SCADA) client using NeoSCADA implementation.</description>
-
- <properties>
- <camel.quarkus.jvmSince>1.1.0</camel.quarkus.jvmSince>
- <cq.descriptionSync>false</cq.descriptionSync>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-iec60870</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/extensions-jvm/iec60870/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions-jvm/iec60870/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 8fb3503fe9..0000000000
--- a/extensions-jvm/iec60870/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel IEC 60870 Client"
-description: "IEC 60870 supervisory control and data acquisition (SCADA) client using NeoSCADA implementation"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- unlisted: true
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/iec60870.html"
- categories:
- - "integration"
- status: "stable"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions-jvm/irc/deployment/pom.xml b/extensions-jvm/irc/deployment/pom.xml
deleted file mode 100644
index 95c08c738a..0000000000
--- a/extensions-jvm/irc/deployment/pom.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-irc-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-irc-deployment</artifactId>
- <name>Camel Quarkus :: IRC :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-irc</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions-jvm/irc/deployment/src/main/java/org/apache/camel/quarkus/component/irc/deployment/IrcProcessor.java b/extensions-jvm/irc/deployment/src/main/java/org/apache/camel/quarkus/component/irc/deployment/IrcProcessor.java
deleted file mode 100644
index 83e3270740..0000000000
--- a/extensions-jvm/irc/deployment/src/main/java/org/apache/camel/quarkus/component/irc/deployment/IrcProcessor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.quarkus.component.irc.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
-import org.jboss.logging.Logger;
-
-class IrcProcessor {
-
- private static final Logger LOG = Logger.getLogger(IrcProcessor.class);
- private static final String FEATURE = "camel-irc";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- /**
- * Remove this once this extension starts supporting the native mode.
- */
- @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
- @Record(value = ExecutionTime.RUNTIME_INIT)
- void warnJvmInNative(JvmOnlyRecorder recorder) {
- JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
- recorder.warnJvmInNative(FEATURE); // warn at runtime
- }
-}
diff --git a/extensions-jvm/irc/pom.xml b/extensions-jvm/irc/pom.xml
deleted file mode 100644
index 42f092c9a8..0000000000
--- a/extensions-jvm/irc/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions-jvm</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-irc-parent</artifactId>
- <name>Camel Quarkus :: IRC</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions-jvm/irc/runtime/pom.xml b/extensions-jvm/irc/runtime/pom.xml
deleted file mode 100644
index 036b76a247..0000000000
--- a/extensions-jvm/irc/runtime/pom.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-irc-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-irc</artifactId>
- <name>Camel Quarkus :: IRC :: Runtime</name>
- <description>Send and receive messages to/from an IRC chat.</description>
-
- <properties>
- <camel.quarkus.jvmSince>1.1.0</camel.quarkus.jvmSince>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-irc</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/extensions-jvm/irc/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions-jvm/irc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 7a84bd3eba..0000000000
--- a/extensions-jvm/irc/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel IRC"
-description: "Send and receive messages to/from an IRC chat"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- unlisted: true
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/irc.html"
- categories:
- - "integration"
- status: "deprecated"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions-jvm/json-patch/deployment/pom.xml b/extensions-jvm/json-patch/deployment/pom.xml
deleted file mode 100644
index fbd832c657..0000000000
--- a/extensions-jvm/json-patch/deployment/pom.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-json-patch-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-json-patch-deployment</artifactId>
- <name>Camel Quarkus :: JsonPatch :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-json-patch</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions-jvm/json-patch/deployment/src/main/java/org/apache/camel/quarkus/component/json/patch/deployment/JsonPatchProcessor.java b/extensions-jvm/json-patch/deployment/src/main/java/org/apache/camel/quarkus/component/json/patch/deployment/JsonPatchProcessor.java
deleted file mode 100644
index 58bfde78f6..0000000000
--- a/extensions-jvm/json-patch/deployment/src/main/java/org/apache/camel/quarkus/component/json/patch/deployment/JsonPatchProcessor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.quarkus.component.json.patch.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
-import org.jboss.logging.Logger;
-
-class JsonPatchProcessor {
-
- private static final Logger LOG = Logger.getLogger(JsonPatchProcessor.class);
- private static final String FEATURE = "camel-json-patch";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- /**
- * Remove this once this extension starts supporting the native mode.
- */
- @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
- @Record(value = ExecutionTime.RUNTIME_INIT)
- void warnJvmInNative(JvmOnlyRecorder recorder) {
- JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
- recorder.warnJvmInNative(FEATURE); // warn at runtime
- }
-}
diff --git a/extensions-jvm/json-patch/pom.xml b/extensions-jvm/json-patch/pom.xml
deleted file mode 100644
index 0431cdb40b..0000000000
--- a/extensions-jvm/json-patch/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions-jvm</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-json-patch-parent</artifactId>
- <name>Camel Quarkus :: JsonPatch</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions-jvm/json-patch/runtime/pom.xml b/extensions-jvm/json-patch/runtime/pom.xml
deleted file mode 100644
index 47e8841de4..0000000000
--- a/extensions-jvm/json-patch/runtime/pom.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-json-patch-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-json-patch</artifactId>
- <name>Camel Quarkus :: JsonPatch :: Runtime</name>
- <description>Transforms JSON using JSON patch (RFC 6902).</description>
-
- <properties>
- <camel.quarkus.jvmSince>2.7.0</camel.quarkus.jvmSince>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-json-patch</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions-jvm/json-patch/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions-jvm/json-patch/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 4187e477eb..0000000000
--- a/extensions-jvm/json-patch/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel JsonPatch"
-description: "Transforms JSON using JSON patch (RFC 6902)"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- unlisted: true
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/json-patch.html"
- categories:
- - "integration"
- status: "deprecated"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index 19d3d1e3c0..0350e429e8 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -62,15 +62,12 @@
<module>google-functions</module>
<module>huaweicloud-smn</module>
<module>ibm-secrets-manager</module>
- <module>iec60870</module>
<module>ignite</module>
- <module>irc</module>
<module>javascript</module>
<module>jcr</module>
<module>jgroups</module>
<module>jgroups-raft</module>
<module>jooq</module>
- <module>json-patch</module>
<module>jsonapi</module>
<module>ldif</module>
<module>lucene</module>
diff --git a/extensions/ai-tool/runtime/src/main/doc/usage.adoc b/extensions/ai-tool/runtime/src/main/doc/usage.adoc
index cec5fd7f4c..2aa04eaca4 100644
--- a/extensions/ai-tool/runtime/src/main/doc/usage.adoc
+++ b/extensions/ai-tool/runtime/src/main/doc/usage.adoc
@@ -1,4 +1,4 @@
-The `ai-tool` component is a framework-agnostic consumer endpoint that registers Camel routes as LLM-callable tools in a shared `AiToolRegistry`. Framework-specific extensions (such as `camel-quarkus-langchain4j-tools`, `camel-quarkus-openai`) discover and invoke these tools at runtime.
+The `ai-tool` component is a framework-agnostic consumer endpoint that registers Camel routes as LLM-callable tools in a shared `AiToolRegistry`. Framework-specific extensions (such as `camel-quarkus-langchain4j-agent`, `camel-quarkus-openai`) discover and invoke these tools at runtime.
=== Defining a tool
diff --git a/extensions/crypto/deployment/src/main/java/org/apache/camel/quarkus/component/crypto/deployment/CryptoProcessor.java b/extensions/crypto/deployment/src/main/java/org/apache/camel/quarkus/component/crypto/deployment/CryptoProcessor.java
index 42e2c91683..3155d29656 100644
--- a/extensions/crypto/deployment/src/main/java/org/apache/camel/quarkus/component/crypto/deployment/CryptoProcessor.java
+++ b/extensions/crypto/deployment/src/main/java/org/apache/camel/quarkus/component/crypto/deployment/CryptoProcessor.java
@@ -19,6 +19,8 @@ package org.apache.camel.quarkus.component.crypto.deployment;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
+import org.apache.camel.converter.crypto.CryptoDataFormat;
import org.jboss.logging.Logger;
class CryptoProcessor {
@@ -37,4 +39,10 @@ class CryptoProcessor {
return new ExtensionSslNativeSupportBuildItem(FEATURE);
}
+ @BuildStep
+ RuntimeInitializedClassBuildItem runtimeInitializedClasses() {
+ // CryptoDataFormat holds a static SecureRandom, which must not be created at build time
+ return new RuntimeInitializedClassBuildItem(CryptoDataFormat.class.getName());
+ }
+
}
diff --git a/extensions/csimple/deployment/pom.xml b/extensions/csimple/deployment/pom.xml
deleted file mode 100644
index 8423f86c27..0000000000
--- a/extensions/csimple/deployment/pom.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-csimple-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-csimple-deployment</artifactId>
- <name>Camel Quarkus :: CSimple :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-support-language-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-csimple</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions/csimple/deployment/src/main/java/org/apache/camel/quarkus/component/csimple/deployment/CSimpleExpressionSourceBuildItem.java b/extensions/csimple/deployment/src/main/java/org/apache/camel/quarkus/component/csimple/deployment/CSimpleExpressionSourceBuildItem.java
deleted file mode 100644
index b1a67232a8..0000000000
--- a/extensions/csimple/deployment/src/main/java/org/apache/camel/quarkus/component/csimple/deployment/CSimpleExpressionSourceBuildItem.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.quarkus.component.csimple.deployment;
-
-import io.quarkus.builder.item.MultiBuildItem;
-
-/**
- * A {@link MultiBuildItem} bearing info about a CSimple language expression that needs to get compiled.
- */
-public final class CSimpleExpressionSourceBuildItem extends MultiBuildItem {
-
- private final String sourceCode;
- private final String classNameBase;
- private final boolean predicate;
-
- public CSimpleExpressionSourceBuildItem(String sourceCode, boolean predicate, String classNameBase) {
- this.sourceCode = sourceCode;
- this.predicate = predicate;
- this.classNameBase = classNameBase;
- }
-
- /**
- * @return the expression source code to compile
- */
- public String getSourceCode() {
- return sourceCode;
- }
-
- /**
- * @return a fully qualified class name that the compiler may use as a base for the name of the class into which it
- * compiles the source code returned by {@link #getSourceCode()}
- */
- public String getClassNameBase() {
- return classNameBase;
- }
-
- /**
- * @return {@code true} if the expression is a predicate; {@code false} otherwise
- */
- public boolean isPredicate() {
- return predicate;
- }
-
-}
diff --git a/extensions/csimple/deployment/src/main/java/org/apache/camel/quarkus/component/csimple/deployment/CSimpleProcessor.java b/extensions/csimple/deployment/src/main/java/org/apache/camel/quarkus/component/csimple/deployment/CSimpleProcessor.java
deleted file mode 100644
index 9e354bb9cb..0000000000
--- a/extensions/csimple/deployment/src/main/java/org/apache/camel/quarkus/component/csimple/deployment/CSimpleProcessor.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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.quarkus.component.csimple.deployment;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import io.quarkus.bootstrap.classloading.ClassPathElement;
-import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
-import io.quarkus.deployment.annotations.BuildProducer;
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.Consume;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
-import io.quarkus.deployment.dev.CompilationProvider;
-import io.quarkus.deployment.dev.CompilationProvider.Context;
-import io.quarkus.deployment.dev.JavaCompilationProvider;
-import io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem;
-import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
-import io.quarkus.deployment.recording.RecorderContext;
-import io.quarkus.runtime.RuntimeValue;
-import org.apache.camel.Exchange;
-import org.apache.camel.language.csimple.CSimpleCodeGenerator;
-import org.apache.camel.language.csimple.CSimpleGeneratedCode;
-import org.apache.camel.language.csimple.CSimpleHelper;
-import org.apache.camel.language.csimple.CSimpleLanguage;
-import org.apache.camel.language.csimple.CSimpleLanguage.Builder;
-import org.apache.camel.quarkus.component.csimple.CSimpleLanguageRecorder;
-import org.apache.camel.quarkus.core.deployment.spi.CamelBeanBuildItem;
-import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
-import org.apache.camel.quarkus.core.deployment.spi.CompiledCSimpleExpressionBuildItem;
-import org.apache.camel.quarkus.core.deployment.util.CamelSupport;
-import org.apache.camel.quarkus.core.util.FileUtils;
-import org.apache.camel.quarkus.support.language.deployment.ExpressionBuildItem;
-import org.apache.camel.quarkus.support.language.deployment.ExpressionExtractionResultBuildItem;
-import org.apache.camel.util.PropertiesHelper;
-import org.jboss.logging.Logger;
-
-class CSimpleProcessor {
-
- private static final Logger LOG = Logger.getLogger(CSimpleProcessor.class);
- private static final String CLASS_NAME = "CompiledExpression";
- private static final String PACKAGE_NAME = "org.apache.camel.quarkus.component.csimple.generated";
- static final String CLASS_EXT = ".class";
- private static final String FEATURE = "camel-csimple";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- @BuildStep
- void collectCSimpleExpressions(
- ExpressionExtractionResultBuildItem result,
- List<ExpressionBuildItem> expressions,
- BuildProducer<CSimpleExpressionSourceBuildItem> csimpleExpressions) {
-
- if (result.isSuccess()) {
- int counter = 0;
- for (ExpressionBuildItem expression : expressions) {
- if ("csimple".equals(expression.getLanguage())) {
- csimpleExpressions.produce(
- new CSimpleExpressionSourceBuildItem(
- expression.getExpression(),
- expression.isPredicate(),
- String.format("%s.%s_%d", PACKAGE_NAME, CLASS_NAME, ++counter)));
- }
- }
- }
- }
-
- @BuildStep
- void compileCSimpleExpressions(
- BuildSystemTargetBuildItem buildSystemTargetBuildItem,
- List<CSimpleExpressionSourceBuildItem> expressionSources,
- BuildProducer<CompiledCSimpleExpressionBuildItem> compiledCSimpleExpression,
- BuildProducer<GeneratedClassBuildItem> generatedClasses) throws IOException {
-
- if (!expressionSources.isEmpty()) {
- final Set<String> imports = new TreeSet<>();
- final Map<String, String> aliases = new LinkedHashMap<>();
- final ClassLoader loader = Thread.currentThread().getContextClassLoader();
- if (!(loader instanceof QuarkusClassLoader)) {
- throw new IllegalStateException(
- QuarkusClassLoader.class.getSimpleName() + " expected as the context class loader");
- }
- final QuarkusClassLoader quarkusClassLoader = (QuarkusClassLoader) loader;
- readConfig(imports, aliases, loader);
- final CSimpleCodeGenerator generator = new CSimpleCodeGenerator();
- generator.setAliases(aliases);
- generator.setImports(imports);
-
- final Path projectDir = Paths.get(".").toAbsolutePath().normalize();
- final Path outputDirectory = buildSystemTargetBuildItem.getOutputDirectory();
- final Path csimpleGeneratedSourceDir = outputDirectory.resolve("generated/csimple");
- Files.createDirectories(csimpleGeneratedSourceDir);
-
- final Set<File> filesToCompile = new LinkedHashSet<>();
-
- /* We do not want to compile the same source twice, so we store here what we have compiled already */
- final Map<Boolean, Set<String>> compiledExpressions = new HashMap<>();
- compiledExpressions.put(true, new HashSet<>());
- compiledExpressions.put(false, new HashSet<>());
-
- /* Generate Java classes for the language expressions */
- for (CSimpleExpressionSourceBuildItem expr : expressionSources) {
- final boolean predicate = expr.isPredicate();
- final String script = expr.getSourceCode();
- if (!compiledExpressions.get(predicate).contains(script)) {
- final CSimpleGeneratedCode code = predicate
- ? generator.generatePredicate(expr.getClassNameBase(), script)
- : generator.generateExpression(expr.getClassNameBase(), script);
-
- compiledCSimpleExpression
- .produce(new CompiledCSimpleExpressionBuildItem(code.getCode(), predicate, code.getFqn()));
-
- final Path javaCsimpleFile = csimpleGeneratedSourceDir
- .resolve(code.getFqn().replace('.', '/') + ".java");
- Files.createDirectories(javaCsimpleFile.getParent());
- Files.write(javaCsimpleFile, code.getCode().getBytes(StandardCharsets.UTF_8));
- filesToCompile.add(javaCsimpleFile.toFile());
- compiledExpressions.get(predicate).add(script);
- }
- }
-
- final Path csimpleClassesDir = outputDirectory.resolve("csimple-classes");
- Files.createDirectories(csimpleClassesDir);
-
- /* Compile the generated sources */
- try (JavaCompilationProvider compiler = new JavaCompilationProvider()) {
- final Context context = compilationContext(projectDir, csimpleClassesDir, quarkusClassLoader);
- compiler.compile(filesToCompile, context);
- }
-
- /* Register the compiled classes via Quarkus GeneratedClassBuildItem */
- try (Stream<Path> classFiles = Files.walk(csimpleClassesDir)) {
- classFiles
- .filter(Files::isRegularFile)
- .filter(p -> p.getFileName().toString().endsWith(CLASS_EXT))
- .forEach(p -> {
- final Path relPath = csimpleClassesDir.relativize(p);
- String className = FileUtils.nixifyPath(relPath.toString());
- className = className.substring(0, className.length() - CLASS_EXT.length());
- try {
- final GeneratedClassBuildItem item = new GeneratedClassBuildItem(true, className,
- Files.readAllBytes(p));
- generatedClasses.produce(item);
- } catch (IOException e) {
- throw new RuntimeException("Could not read " + p);
- }
- });
- }
-
- }
- }
-
- @Record(ExecutionTime.STATIC_INIT)
- @BuildStep
- @Consume(CamelContextBuildItem.class)
- CamelBeanBuildItem configureCSimpleLanguage(
- RecorderContext recorderContext,
- CSimpleLanguageRecorder recorder,
- ExpressionExtractionResultBuildItem result,
- CurateOutcomeBuildItem curateOutcomeBuildItem,
- List<CompiledCSimpleExpressionBuildItem> compiledCSimpleExpressions) {
-
- if (result.isSuccess()) {
- final RuntimeValue<Builder> builder = recorder.csimpleLanguageBuilder();
- for (CompiledCSimpleExpressionBuildItem expr : compiledCSimpleExpressions) {
- recorder.addExpression(builder, recorderContext.newInstance(expr.getClassName()));
- }
-
- final RuntimeValue<?> csimpleLanguage = recorder.buildCSimpleLanguage(builder);
- return new CamelBeanBuildItem("csimple", CSimpleLanguage.class.getName(), csimpleLanguage);
- } else if (curateOutcomeBuildItem.getApplicationModel().getRuntimeDependencies().stream().noneMatch(
- x -> x.getGroupId().equals("org.apache.camel") && x.getArtifactId().equals("camel-csimple-joor"))) {
- LOG.warn(
- "The expression extraction process has been disabled or failed, please add camel-csimple-joor to your classpath to compile the expressions at runtime");
- }
- return null;
- }
-
- static void readConfig(Set<String> imports, Map<String, String> aliases, ClassLoader cl) throws IOException {
- Enumeration<URL> confiUrls = cl.getResources("camel-csimple.properties");
- while (confiUrls.hasMoreElements()) {
- final URL configUrl = confiUrls.nextElement();
- try (BufferedReader r = new BufferedReader(new InputStreamReader(configUrl.openStream(), StandardCharsets.UTF_8))) {
- String line;
- while ((line = r.readLine()) != null) {
- line = line.trim();
- // skip comments
- if (line.startsWith("#")) {
- continue;
- }
- // imports
- if (line.startsWith("import ")) {
- imports.add(line);
- continue;
- }
- // aliases as key=value
- final int eqPos = line.indexOf('=');
- final String key = line.substring(0, eqPos).trim();
- final String value = line.substring(eqPos + 1).trim();
- aliases.put(key, value);
-
- }
- } catch (IOException e) {
- throw new RuntimeException("Could not read from " + configUrl);
- }
- }
- }
-
- private Context compilationContext(final Path projectDir, final Path csimpleClassesDir,
- QuarkusClassLoader quarkusClassLoader) {
- Set<File> classPathElements = Stream.of(CSimpleHelper.class, Exchange.class, PropertiesHelper.class)
- .map(clazz -> clazz.getName().replace('.', '/') + CLASS_EXT)
- .flatMap(className -> (Stream<ClassPathElement>) quarkusClassLoader.getElementsWithResource(className).stream())
- .map(ClassPathElement::getRoot)
- .filter(Objects::nonNull)
- .map(Path::toFile)
- .collect(Collectors.toSet());
-
- return new CompilationProvider.Context(
- "csimple-project",
- classPathElements,
- classPathElements,
- projectDir.toFile(),
- projectDir.resolve("src/main/java").toFile(),
- csimpleClassesDir.toFile(),
- StandardCharsets.UTF_8.name(),
- Map.of(),
- CamelSupport.COMPILATION_JVM_TARGET,
- null,
- null,
-
- List.of(),
- List.of(),
- null,
- Set.of(),
- List.of(),
- null);
- }
-
-}
diff --git a/extensions/csimple/pom.xml b/extensions/csimple/pom.xml
deleted file mode 100644
index a1eaf9488e..0000000000
--- a/extensions/csimple/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-csimple-parent</artifactId>
- <name>Camel Quarkus :: CSimple</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions/csimple/runtime/pom.xml b/extensions/csimple/runtime/pom.xml
deleted file mode 100644
index fc97ed84ef..0000000000
--- a/extensions/csimple/runtime/pom.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-csimple-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-csimple</artifactId>
- <name>Camel Quarkus :: CSimple :: Runtime</name>
- <description>Compiled Simple language</description>
-
- <properties>
- <camel.quarkus.jvmSince>1.5.0</camel.quarkus.jvmSince>
- <camel.quarkus.nativeSince>1.5.0</camel.quarkus.nativeSince>
- <quarkus.metadata.status>preview</quarkus.metadata.status>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-support-language</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions/csimple/runtime/src/main/doc/limitations.adoc b/extensions/csimple/runtime/src/main/doc/limitations.adoc
deleted file mode 100644
index 60c399f6d3..0000000000
--- a/extensions/csimple/runtime/src/main/doc/limitations.adoc
+++ /dev/null
@@ -1,32 +0,0 @@
-CSimple language is supported in all existing DSLs, but be aware that to extract the expressions from the existing route definitions, a dry run is done during the startup in JVM mode or during the build in Native mode which adds some log entries of the following type that you can simply ignore.
-
-[source,text]
-----
-2023-01-19 16:36:31,779 INFO [org.apa.cam.mai.MainSupport] (build-10) Expression Extractor 3.20.1 is starting
-2023-01-19 16:36:32,214 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (build-10) Apache Camel 3.20.1 (Expression Extractor) is starting
-2023-01-19 16:36:32,216 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (build-10) Routes startup (started:0)
-2023-01-19 16:36:32,217 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (build-10) Apache Camel 3.20.1 (Expression Extractor) started in 128ms (build:22ms init:104ms start:2ms)
-2023-01-19 16:36:32,218 INFO [org.apa.cam.mai.MainSupport] (build-10) Waiting until complete: Duration max 1 seconds
-2023-01-19 16:36:33,223 INFO [org.apa.cam.mai.MainSupport] (build-10) Duration max seconds triggering shutdown of the JVM
-2023-01-19 16:36:33,223 INFO [org.apa.cam.mai.MainSupport] (build-10) Expression Extractor 3.20.1 shutdown
-----
-
-The compilation of CSimple scripts happens at build time by default. To be able to discover the scripts in the route definitions,
-those definitions need to get assembled at build time. When extending
-`org.apache.camel.builder.RouteBuilder`, this basically means instantiating your `RouteBuilder`, setting
-a fake `CamelContext` instance on it and calling its `configure()` method. It may fail if your `configure()`
-method attempts to access some resource that is only available at runtime.
-
-You can use the `quarkus.camel.expression.on-build-time-analysis-failure` configuration parameter to decide
-what should happen in such cases. Possible values are `warn` (default), `fail` or `ignore`.
-
-You can also simply disable the expression extraction process by setting the configuration parameter `quarkus.camel.expression.extraction-enabled` to `false`.
-
-If the expression extraction process is disabled or fails, the expressions are then compiled at runtime which also means that it
-can only work in JVM mode moreover the artifact `org.apache.camel:camel-csimple-joor` has to be added to the classpath.
-
-[WARNING]
-====
-CSimple language will not work on Camel Quarkus if used in a `org.apache.camel.builder.LambdaRouteBuilder` or if a `RouteBuilder` depends on dependency injection.
-====
-
diff --git a/extensions/csimple/runtime/src/main/java/org/apache/camel/quarkus/component/csimple/CSimpleLanguageRecorder.java b/extensions/csimple/runtime/src/main/java/org/apache/camel/quarkus/component/csimple/CSimpleLanguageRecorder.java
deleted file mode 100644
index b58b94208c..0000000000
--- a/extensions/csimple/runtime/src/main/java/org/apache/camel/quarkus/component/csimple/CSimpleLanguageRecorder.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.quarkus.component.csimple;
-
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.language.csimple.CSimpleExpression;
-import org.apache.camel.language.csimple.CSimpleLanguage;
-import org.apache.camel.language.csimple.CSimpleLanguage.Builder;
-
-@Recorder
-public class CSimpleLanguageRecorder {
-
- public RuntimeValue<CSimpleLanguage.Builder> csimpleLanguageBuilder() {
- return new RuntimeValue<>(CSimpleLanguage.builder());
- }
-
- public void addExpression(RuntimeValue<Builder> builder, RuntimeValue<CSimpleExpression> expression) {
- builder.getValue().expression(expression.getValue());
- }
-
- public RuntimeValue<?> buildCSimpleLanguage(RuntimeValue<Builder> builder) {
- return new RuntimeValue<>(builder.getValue().build());
- }
-
-}
diff --git a/extensions/csimple/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/csimple/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index db87cfbc26..0000000000
--- a/extensions/csimple/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel CSimple"
-description: "Compiled Simple language"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/csimple.html"
- categories:
- - "integration"
- status: "preview"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions/digitalocean/deployment/pom.xml b/extensions/digitalocean/deployment/pom.xml
deleted file mode 100644
index c4f694269e..0000000000
--- a/extensions/digitalocean/deployment/pom.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-digitalocean-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-digitalocean-deployment</artifactId>
- <name>Camel Quarkus :: DigitalOcean :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-digitalocean</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-support-commons-logging-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-support-httpclient-deployment</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions/digitalocean/deployment/src/main/java/org/apache/camel/quarkus/component/digitalocean/deployment/DigitaloceanProcessor.java b/extensions/digitalocean/deployment/src/main/java/org/apache/camel/quarkus/component/digitalocean/deployment/DigitaloceanProcessor.java
deleted file mode 100644
index a75a356cf3..0000000000
--- a/extensions/digitalocean/deployment/src/main/java/org/apache/camel/quarkus/component/digitalocean/deployment/DigitaloceanProcessor.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.deployment;
-
-import io.quarkus.deployment.annotations.BuildProducer;
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
-import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
-import org.jboss.jandex.IndexView;
-
-class DigitaloceanProcessor {
-
- private static final String FEATURE = "camel-digitalocean";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- @BuildStep
- ExtensionSslNativeSupportBuildItem activateSslNativeSupport() {
- return new ExtensionSslNativeSupportBuildItem(FEATURE);
- }
-
- @BuildStep
- ReflectiveClassBuildItem registerForReflection(CombinedIndexBuildItem combinedIndex) {
- IndexView index = combinedIndex.getIndex();
- // register Digitalocean model classes for JSON serialize/deserialize
- String[] dtos = index.getKnownClasses().stream().map(ci -> ci.name().toString())
- .filter(n -> n.startsWith("com.myjeeva.digitalocean.pojo")
- || n.startsWith("com.myjeeva.digitalocean.common"))
- .toArray(String[]::new);
-
- return ReflectiveClassBuildItem.builder(dtos).methods().fields().build();
- }
-
- @BuildStep
- void addDependencies(BuildProducer<IndexDependencyBuildItem> indexDependency) {
- indexDependency.produce(new IndexDependencyBuildItem("com.myjeeva.digitalocean", "digitalocean-api-client"));
- }
-
-}
diff --git a/extensions/digitalocean/pom.xml b/extensions/digitalocean/pom.xml
deleted file mode 100644
index a16b60add9..0000000000
--- a/extensions/digitalocean/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-digitalocean-parent</artifactId>
- <name>Camel Quarkus :: DigitalOcean</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions/digitalocean/runtime/pom.xml b/extensions/digitalocean/runtime/pom.xml
deleted file mode 100644
index 6714526b5f..0000000000
--- a/extensions/digitalocean/runtime/pom.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-digitalocean-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-digitalocean</artifactId>
- <name>Camel Quarkus :: DigitalOcean :: Runtime</name>
- <description>Manage Droplets and resources within the DigitalOcean cloud.</description>
-
- <properties>
- <camel.quarkus.jvmSince>1.1.0</camel.quarkus.jvmSince>
- <camel.quarkus.nativeSince>2.0.0</camel.quarkus.nativeSince>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-digitalocean</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-support-commons-logging</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-support-httpclient</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/extensions/digitalocean/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/digitalocean/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 58b3e03cde..0000000000
--- a/extensions/digitalocean/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel DigitalOcean"
-description: "Manage Droplets and resources within the DigitalOcean cloud"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/digitalocean.html"
- categories:
- - "integration"
- status: "deprecated"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions/hazelcast/deployment/pom.xml b/extensions/hazelcast/deployment/pom.xml
index 54212e75f7..e40ef599cc 100644
--- a/extensions/hazelcast/deployment/pom.xml
+++ b/extensions/hazelcast/deployment/pom.xml
@@ -27,7 +27,7 @@
</parent>
<artifactId>camel-quarkus-hazelcast-deployment</artifactId>
- <name>Camel Quarkus :: Hazelcast Atomic Number :: Deployment</name>
+ <name>Camel Quarkus :: Hazelcast :: Deployment</name>
<dependencies>
<dependency>
diff --git a/extensions/hazelcast/pom.xml b/extensions/hazelcast/pom.xml
index ae6d80b6d7..420376fe26 100644
--- a/extensions/hazelcast/pom.xml
+++ b/extensions/hazelcast/pom.xml
@@ -27,7 +27,7 @@
</parent>
<artifactId>camel-quarkus-hazelcast-parent</artifactId>
- <name>Camel Quarkus :: Hazelcast Atomic Number</name>
+ <name>Camel Quarkus :: Hazelcast</name>
<packaging>pom</packaging>
<modules>
diff --git a/extensions/hazelcast/runtime/pom.xml b/extensions/hazelcast/runtime/pom.xml
index 1b56d07c80..2a25f8efeb 100644
--- a/extensions/hazelcast/runtime/pom.xml
+++ b/extensions/hazelcast/runtime/pom.xml
@@ -27,8 +27,8 @@
</parent>
<artifactId>camel-quarkus-hazelcast</artifactId>
- <name>Camel Quarkus :: Hazelcast Atomic Number :: Runtime</name>
- <description>Increment, decrement, set, etc. Hazelcast atomic number (a grid wide number).</description>
+ <name>Camel Quarkus :: Hazelcast :: Runtime</name>
+ <description>Perform operations on Hazelcast distributed data structures such as map, multimap, list, set, queue, topic and ringbuffer.</description>
<properties>
<camel.quarkus.jvmSince>1.1.0</camel.quarkus.jvmSince>
diff --git a/extensions/hazelcast/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/hazelcast/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 5d11296bad..e3f46e959b 100644
--- a/extensions/hazelcast/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/hazelcast/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -21,8 +21,8 @@
# mvn -N cq:update-quarkus-metadata
#
---
-name: "Camel Hazelcast Atomic Number"
-description: "Increment, decrement, set, etc. Hazelcast atomic number (a grid wide number)"
+name: "Camel Hazelcast"
+description: "Perform operations on Hazelcast distributed data structures such as map, multimap, list, set, queue, topic and ringbuffer"
metadata:
icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
sponsor: "Apache Software Foundation"
diff --git a/extensions/headersmap/deployment/pom.xml b/extensions/headersmap/deployment/pom.xml
deleted file mode 100644
index 907dddc224..0000000000
--- a/extensions/headersmap/deployment/pom.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-headersmap-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-headersmap-deployment</artifactId>
- <name>Camel Quarkus :: Headersmap :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-headersmap</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions/headersmap/deployment/src/main/java/org/apache/camel/quarkus/component/headersmap/deployment/HeadersmapProcessor.java b/extensions/headersmap/deployment/src/main/java/org/apache/camel/quarkus/component/headersmap/deployment/HeadersmapProcessor.java
deleted file mode 100644
index 5df8195f6c..0000000000
--- a/extensions/headersmap/deployment/src/main/java/org/apache/camel/quarkus/component/headersmap/deployment/HeadersmapProcessor.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.quarkus.component.headersmap.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import org.apache.camel.quarkus.component.headersmap.CamelHeadersmapRecorder;
-import org.apache.camel.quarkus.core.deployment.spi.CamelContextCustomizerBuildItem;
-
-class HeadersmapProcessor {
-
- private static final String FEATURE = "camel-headersmap";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- @Record(ExecutionTime.STATIC_INIT)
- @BuildStep
- CamelContextCustomizerBuildItem fastHeadersMapCamelContextCustomizer(CamelHeadersmapRecorder recorder) {
- return new CamelContextCustomizerBuildItem(recorder.createFastHeadersMapFactory());
- }
-}
diff --git a/extensions/headersmap/pom.xml b/extensions/headersmap/pom.xml
deleted file mode 100644
index ae062acd26..0000000000
--- a/extensions/headersmap/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-headersmap-parent</artifactId>
- <name>Camel Quarkus :: Headersmap</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions/headersmap/runtime/pom.xml b/extensions/headersmap/runtime/pom.xml
deleted file mode 100644
index b45ee9a04c..0000000000
--- a/extensions/headersmap/runtime/pom.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-headersmap-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-headersmap</artifactId>
- <name>Camel Quarkus :: Headersmap :: Runtime</name>
- <description>Fast case-insensitive headers map implementation</description>
-
- <properties>
- <camel.quarkus.jvmSince>1.2.0</camel.quarkus.jvmSince>
- <camel.quarkus.nativeSince>1.2.0</camel.quarkus.nativeSince>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-headersmap</artifactId>
- </dependency>
- <dependency>
- <groupId>org.graalvm.sdk</groupId>
- <artifactId>nativeimage</artifactId>
- <scope>provided</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/extensions/headersmap/runtime/src/main/java/org/apache/camel/quarkus/component/headersmap/CamelHeadersmapRecorder.java b/extensions/headersmap/runtime/src/main/java/org/apache/camel/quarkus/component/headersmap/CamelHeadersmapRecorder.java
deleted file mode 100644
index 0203a39671..0000000000
--- a/extensions/headersmap/runtime/src/main/java/org/apache/camel/quarkus/component/headersmap/CamelHeadersmapRecorder.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.quarkus.component.headersmap;
-
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.CamelContext;
-import org.apache.camel.component.headersmap.FastHeadersMapFactory;
-import org.apache.camel.spi.CamelContextCustomizer;
-
-@Recorder
-public class CamelHeadersmapRecorder {
-
- public RuntimeValue<CamelContextCustomizer> createFastHeadersMapFactory() {
- return new RuntimeValue<>(new CamelContextCustomizer() {
- @Override
- public void configure(CamelContext context) {
- context.getCamelContextExtension().setHeadersMapFactory(new FastHeadersMapFactory());
- }
- });
- }
-}
diff --git a/extensions/headersmap/runtime/src/main/java/org/apache/camel/quarkus/component/headersmap/graal/ThreadedLRUCacheStrategySubstitutions.java b/extensions/headersmap/runtime/src/main/java/org/apache/camel/quarkus/component/headersmap/graal/ThreadedLRUCacheStrategySubstitutions.java
deleted file mode 100644
index 43230c4c8f..0000000000
--- a/extensions/headersmap/runtime/src/main/java/org/apache/camel/quarkus/component/headersmap/graal/ThreadedLRUCacheStrategySubstitutions.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.quarkus.component.headersmap.graal;
-
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-
-import com.cedarsoftware.util.cache.ThreadedLRUCacheStrategy;
-import com.oracle.svm.core.annotate.Alias;
-import com.oracle.svm.core.annotate.RecomputeFieldValue;
-import com.oracle.svm.core.annotate.TargetClass;
-
-@TargetClass(ThreadedLRUCacheStrategy.class)
-final class ThreadedLRUCacheStrategySubstitutions {
- @Alias
- @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias)
- private static ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
- @Override
- public Thread newThread(Runnable r) {
- Thread thread = new Thread(r, "LRUCache-Purge-Thread");
- thread.setDaemon(true);
- return thread;
- }
- });
-}
diff --git a/extensions/headersmap/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/headersmap/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 3a84f85251..0000000000
--- a/extensions/headersmap/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel Headersmap"
-description: "Fast case-insensitive headers map implementation"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/headersmap.html"
- categories:
- - "integration"
- status: "deprecated"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions/jolt/deployment/src/main/java/org/apache/camel/quarkus/component/jolt/deployment/JoltProcessor.java b/extensions/jolt/deployment/src/main/java/org/apache/camel/quarkus/component/jolt/deployment/JoltProcessor.java
index b964685553..d519dd1480 100644
--- a/extensions/jolt/deployment/src/main/java/org/apache/camel/quarkus/component/jolt/deployment/JoltProcessor.java
+++ b/extensions/jolt/deployment/src/main/java/org/apache/camel/quarkus/component/jolt/deployment/JoltProcessor.java
@@ -16,7 +16,7 @@
*/
package org.apache.camel.quarkus.component.jolt.deployment;
-import com.bazaarvoice.jolt.chainr.spec.ChainrEntry;
+import io.joltcommunity.jolt.chainr.spec.ChainrEntry;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.FeatureBuildItem;
diff --git a/extensions/joor/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/joor/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 514401cb2d..857117fc7d 100644
--- a/extensions/joor/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/joor/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -31,7 +31,7 @@ metadata:
- "integration"
config:
- "quarkus.camel.joor"
- status: "deprecated"
+ status: "stable"
integrates:
- name: "Camel"
artifact: "org.apache.camel:camel-base"
diff --git a/extensions/langchain4j-ingest/runtime/pom.xml b/extensions/langchain4j-ingest/runtime/pom.xml
index a03f1b28a5..bf77d71837 100644
--- a/extensions/langchain4j-ingest/runtime/pom.xml
+++ b/extensions/langchain4j-ingest/runtime/pom.xml
@@ -28,7 +28,7 @@
<artifactId>camel-quarkus-langchain4j-ingest</artifactId>
<name>Camel Quarkus :: LangChain4j Ingest :: Runtime</name>
- <description>Declarative AI document ingestion: point a knowledge base at a folder via configuration; splitting, embedding and storing are handled under the hood</description>
+ <description>Ingest documents into a LangChain4j EmbeddingStore: split, embed and store the message body.</description>
<properties>
<camel.quarkus.jvmSince>3.39.0</camel.quarkus.jvmSince>
diff --git a/extensions/langchain4j-ingest/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/langchain4j-ingest/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 4f80136572..3375816425 100644
--- a/extensions/langchain4j-ingest/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/langchain4j-ingest/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -22,7 +22,7 @@
#
---
name: "Camel LangChain4j Ingest"
-description: "Declarative AI document ingestion: point a knowledge base at a folder via configuration; splitting, embedding and storing are handled under the hood"
+description: "Ingest documents into a LangChain4j EmbeddingStore: split, embed and store the message body"
metadata:
icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
sponsor: "Apache Software Foundation"
diff --git a/extensions/langchain4j-tools/deployment/pom.xml b/extensions/langchain4j-tools/deployment/pom.xml
deleted file mode 100644
index 90cf14a0bf..0000000000
--- a/extensions/langchain4j-tools/deployment/pom.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-langchain4j-tools-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-langchain4j-tools-deployment</artifactId>
- <name>Camel Quarkus :: LangChain4j Tools :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-support-langchain4j-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-langchain4j-tools</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions/langchain4j-tools/deployment/src/main/java/org/apache/camel/quarkus/component/langchain4j/tools/deployment/Langchain4jToolsProcessor.java b/extensions/langchain4j-tools/deployment/src/main/java/org/apache/camel/quarkus/component/langchain4j/tools/deployment/Langchain4jToolsProcessor.java
deleted file mode 100644
index 84afa8bdd8..0000000000
--- a/extensions/langchain4j-tools/deployment/src/main/java/org/apache/camel/quarkus/component/langchain4j/tools/deployment/Langchain4jToolsProcessor.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.quarkus.component.langchain4j.tools.deployment;
-
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-
-class Langchain4jToolsProcessor {
- private static final String FEATURE = "camel-langchain4j-tools";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-}
diff --git a/extensions/langchain4j-tools/pom.xml b/extensions/langchain4j-tools/pom.xml
deleted file mode 100644
index 0be4e0b8ae..0000000000
--- a/extensions/langchain4j-tools/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-langchain4j-tools-parent</artifactId>
- <name>Camel Quarkus :: LangChain4j Tools</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions/langchain4j-tools/runtime/pom.xml b/extensions/langchain4j-tools/runtime/pom.xml
deleted file mode 100644
index 1db0bea184..0000000000
--- a/extensions/langchain4j-tools/runtime/pom.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-langchain4j-tools-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-langchain4j-tools</artifactId>
- <name>Camel Quarkus :: LangChain4j Tools :: Runtime</name>
- <description>LangChain4j Tools and Function Calling Features</description>
-
- <properties>
- <camel.quarkus.jvmSince>3.15.0</camel.quarkus.jvmSince>
- <camel.quarkus.nativeSince>3.24.0</camel.quarkus.nativeSince>
- <quarkus.metadata.status>preview</quarkus.metadata.status>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-support-langchain4j</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-langchain4j-tools</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-
- <profiles>
- <profile>
- <id>full</id>
- <activation>
- <property>
- <name>!quickly</name>
- </property>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>update-extension-doc-page</id>
- <goals>
- <goal>update-extension-doc-page</goal>
- </goals>
- <phase>process-classes</phase>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
-</project>
diff --git a/extensions/langchain4j-tools/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/langchain4j-tools/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 73d316516a..0000000000
--- a/extensions/langchain4j-tools/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel LangChain4j Tools"
-description: "LangChain4j Tools and Function Calling Features"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/langchain4j-tools.html"
- categories:
- - "integration"
- status: "deprecated"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions/leveldb/deployment/pom.xml b/extensions/leveldb/deployment/pom.xml
deleted file mode 100644
index 40105b66e4..0000000000
--- a/extensions/leveldb/deployment/pom.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-leveldb-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-leveldb-deployment</artifactId>
- <name>Camel Quarkus :: LevelDB :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-leveldb</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-jackson-deployment</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions/leveldb/deployment/src/main/java/org/apache/camel/quarkus/component/leveldb/deployment/LeveldbProcessor.java b/extensions/leveldb/deployment/src/main/java/org/apache/camel/quarkus/component/leveldb/deployment/LeveldbProcessor.java
deleted file mode 100644
index f848cf8696..0000000000
--- a/extensions/leveldb/deployment/src/main/java/org/apache/camel/quarkus/component/leveldb/deployment/LeveldbProcessor.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.quarkus.component.leveldb.deployment;
-
-import io.quarkus.deployment.annotations.BuildProducer;
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
-import org.apache.camel.support.DefaultExchangeHolder;
-import org.iq80.leveldb.impl.Iq80DBFactory;
-
-class LeveldbProcessor {
-
- private static final String FEATURE = "camel-leveldb";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- @BuildStep
- ReflectiveClassBuildItem registerForReflection() {
- return ReflectiveClassBuildItem.builder(Iq80DBFactory.class.getName()).build();
- }
-
- @BuildStep
- ReflectiveClassBuildItem registerForReflectionWithFields() {
- return ReflectiveClassBuildItem.builder(DefaultExchangeHolder.class.getName()).fields().build();
- }
-
- @BuildStep
- public void registerRuntimeInitializedClasses(BuildProducer<RuntimeInitializedClassBuildItem> resource) {
- resource.produce(new RuntimeInitializedClassBuildItem(
- org.iq80.leveldb.table.Table.class.getName()));
- }
-}
diff --git a/extensions/leveldb/pom.xml b/extensions/leveldb/pom.xml
deleted file mode 100644
index 6d250fd811..0000000000
--- a/extensions/leveldb/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-leveldb-parent</artifactId>
- <name>Camel Quarkus :: LevelDB</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions/leveldb/runtime/pom.xml b/extensions/leveldb/runtime/pom.xml
deleted file mode 100644
index e07dba0a18..0000000000
--- a/extensions/leveldb/runtime/pom.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-leveldb-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-leveldb</artifactId>
- <name>Camel Quarkus :: LevelDB :: Runtime</name>
- <description>Using LevelDB as persistent EIP store</description>
-
- <properties>
- <camel.quarkus.jvmSince>1.2.0</camel.quarkus.jvmSince>
- <camel.quarkus.nativeSince>1.2.0</camel.quarkus.nativeSince>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-leveldb</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>leveldbjni-all</artifactId>
- <groupId>org.fusesource.leveldbjni</groupId>
- </exclusion>
- <exclusion>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-jackson</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/extensions/leveldb/runtime/src/main/doc/limitations.adoc b/extensions/leveldb/runtime/src/main/doc/limitations.adoc
deleted file mode 100644
index 2c29c2b025..0000000000
--- a/extensions/leveldb/runtime/src/main/doc/limitations.adoc
+++ /dev/null
@@ -1,14 +0,0 @@
-In native mode the extension uses a port of LevelDB written in Java (https://github.com/dain/leveldb#leveldb-in-java[documentation]),
-which is within 10% of the performance of the C++ original. Please upvote https://github.com/apache/camel-quarkus/issues/1911[this issue]
-if you do not like the present state.
-
-Serialization is https://github.com/oracle/graal/issues/460[not supported] on GraalVM. Extension has to use serialization based
-on Jackson. Aggregation repository in native has to be constructed in one of the following ways:
-
-* Use class `QuarkusLevelDBAggregationRepository` instead of `LevelDBAggregationRepository`.
-* Configure jackson serializer on `LevelDBAggregationRepository` by calling `repo.setSerializer(new JacksonLevelDBSerializer());`
-
-Jackson serializer has limitation towards binary content. If payload object contains binary data (does not concern payloads which are completely binary), Jackson serialization and deserialization won't work correctly.
-To avoid this, define your own jackson serializer/deserializer via `Module` and provide it to the aggregation repository
-(you can use for example the constructor of `QuarkusLevelDBAggregationRepository`).
-
diff --git a/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/QuarkusLevelDBAggregationRepository.java b/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/QuarkusLevelDBAggregationRepository.java
deleted file mode 100644
index 7e930ec116..0000000000
--- a/extensions/leveldb/runtime/src/main/java/org/apache/camel/quarkus/component/leveldb/QuarkusLevelDBAggregationRepository.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.quarkus.component.leveldb;
-
-import com.fasterxml.jackson.databind.Module;
-import org.apache.camel.component.leveldb.LevelDBAggregationRepository;
-import org.apache.camel.component.leveldb.LevelDBFile;
-import org.apache.camel.component.leveldb.serializer.JacksonLevelDBSerializer;
-
-public class QuarkusLevelDBAggregationRepository extends LevelDBAggregationRepository {
-
- public QuarkusLevelDBAggregationRepository() {
- initSerializer(null);
- }
-
- public QuarkusLevelDBAggregationRepository(String repositoryName) {
- super(repositoryName);
- initSerializer(null);
- }
-
- public QuarkusLevelDBAggregationRepository(String repositoryName, String persistentFileName) {
- super(repositoryName, persistentFileName);
- initSerializer(null);
- }
-
- public QuarkusLevelDBAggregationRepository(String repositoryName, LevelDBFile levelDBFile) {
- super(repositoryName, levelDBFile);
- initSerializer(null);
- }
-
- //constructor with module
-
- public QuarkusLevelDBAggregationRepository(Module module) {
- JacksonLevelDBSerializer serializer = new JacksonLevelDBSerializer(module);
- initSerializer(module);
- }
-
- public QuarkusLevelDBAggregationRepository(String repositoryName, Module module) {
- super(repositoryName);
- initSerializer(module);
- }
-
- public QuarkusLevelDBAggregationRepository(String repositoryName, String persistentFileName, Module module) {
- super(repositoryName, persistentFileName);
- initSerializer(module);
- }
-
- public QuarkusLevelDBAggregationRepository(String repositoryName, LevelDBFile levelDBFile, Module module) {
- super(repositoryName, levelDBFile);
- initSerializer(module);
- }
-
- private void initSerializer(Module module) {
- JacksonLevelDBSerializer serializer = new JacksonLevelDBSerializer(module);
- setSerializer(serializer);
- }
-}
diff --git a/extensions/leveldb/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/leveldb/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 272a334811..0000000000
--- a/extensions/leveldb/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel LevelDB"
-description: "Using LevelDB as persistent EIP store"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/leveldb.html"
- categories:
- - "integration"
- status: "deprecated"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/extensions/mcp-server/runtime/pom.xml b/extensions/mcp-server/runtime/pom.xml
index 02f4689051..ba8f9a0643 100644
--- a/extensions/mcp-server/runtime/pom.xml
+++ b/extensions/mcp-server/runtime/pom.xml
@@ -28,7 +28,7 @@
<artifactId>camel-quarkus-mcp-server</artifactId>
<name>Camel Quarkus :: MCP Server :: Runtime</name>
- <description>Expose ai-tool routes as MCP tools over streamable HTTP</description>
+ <description>Expose ai-tool routes as MCP tools and ai-resource routes as MCP resources over streamable HTTP</description>
<properties>
<quarkus.metadata.status>preview</quarkus.metadata.status>
diff --git a/extensions/mcp-server/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/mcp-server/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index c41eb69f6b..fa14a8c72f 100644
--- a/extensions/mcp-server/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/mcp-server/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -22,7 +22,7 @@
#
---
name: "Camel MCP Server"
-description: "Expose ai-tool routes as MCP tools over streamable HTTP"
+description: "Expose ai-tool routes as MCP tools and ai-resource routes as MCP resources over streamable HTTP"
metadata:
icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
sponsor: "Apache Software Foundation"
diff --git a/extensions/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 8ebf4df271..7d3185523f 100644
--- a/extensions/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/minio/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -29,7 +29,7 @@ metadata:
guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/minio.html"
categories:
- "integration"
- status: "stable"
+ status: "deprecated"
integrates:
- name: "Camel"
artifact: "org.apache.camel:camel-base"
diff --git a/extensions/openai/runtime/pom.xml b/extensions/openai/runtime/pom.xml
index a38ad14bec..37df9823f2 100644
--- a/extensions/openai/runtime/pom.xml
+++ b/extensions/openai/runtime/pom.xml
@@ -28,7 +28,7 @@
<artifactId>camel-quarkus-openai</artifactId>
<name>Camel Quarkus :: OpenAI :: Runtime</name>
- <description>OpenAI endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech.</description>
+ <description>LLM endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech using OpenAI-compatible APIs. The openai scheme is a supported alias.</description>
<properties>
<camel.quarkus.jvmSince>3.32.0</camel.quarkus.jvmSince>
diff --git a/extensions/openai/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/openai/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index f5449eb3c2..f4e87c0d82 100644
--- a/extensions/openai/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/extensions/openai/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -22,7 +22,7 @@
#
---
name: "Camel OpenAI"
-description: "OpenAI endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech"
+description: "LLM endpoint for chat completion, Responses API, embeddings, audio transcription, audio translation, and text-to-speech using OpenAI-compatible APIs. The openai scheme is a supported alias"
metadata:
icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
sponsor: "Apache Software Foundation"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index c5baebc797..2eccbe3ad3 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -91,7 +91,6 @@
<module>cron</module>
<module>crypto</module>
<module>crypto-pgp</module>
- <module>csimple</module>
<module>csv</module>
<module>cxf-soap</module>
<module>cyberark-vault</module>
@@ -104,7 +103,6 @@
<module>debezium-postgres</module>
<module>debezium-sqlserver</module>
<module>debug</module>
- <module>digitalocean</module>
<module>direct</module>
<module>disruptor</module>
<module>docling</module>
@@ -139,7 +137,6 @@
<module>gson</module>
<module>hashicorp-vault</module>
<module>hazelcast</module>
- <module>headersmap</module>
<module>hl7</module>
<module>http</module>
<module>ibm-cos</module>
@@ -191,11 +188,9 @@
<module>langchain4j-embeddingstore</module>
<module>langchain4j-ingest</module>
<module>langchain4j-tokenizer</module>
- <module>langchain4j-tools</module>
<module>langchain4j-web-search</module>
<module>language</module>
<module>ldap</module>
- <module>leveldb</module>
<module>log</module>
<module>lra</module>
<module>lumberjack</module>
@@ -274,7 +269,6 @@
<module>snakeyaml</module>
<module>soap</module>
<module>solr</module>
- <module>splunk</module>
<module>splunk-hec</module>
<module>spring-rabbitmq</module>
<module>sql</module>
diff --git a/extensions/splunk/deployment/pom.xml b/extensions/splunk/deployment/pom.xml
deleted file mode 100644
index 24b95b4439..0000000000
--- a/extensions/splunk/deployment/pom.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-splunk-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-splunk-deployment</artifactId>
- <name>Camel Quarkus :: Splunk :: Deployment</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core-deployment</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-splunk</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions/splunk/deployment/src/main/java/org/apache/camel/quarkus/component/splunk/deployment/SplunkProcessor.java b/extensions/splunk/deployment/src/main/java/org/apache/camel/quarkus/component/splunk/deployment/SplunkProcessor.java
deleted file mode 100644
index d2a29432f8..0000000000
--- a/extensions/splunk/deployment/src/main/java/org/apache/camel/quarkus/component/splunk/deployment/SplunkProcessor.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.quarkus.component.splunk.deployment;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.splunk.HttpService;
-import com.splunk.Index;
-import com.splunk.Input;
-import com.splunk.SavedSearch;
-import com.splunk.Service;
-import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
-import io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem;
-import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
-import org.jboss.jandex.DotName;
-import org.jboss.jandex.IndexView;
-import org.joda.time.DateTimeZone;
-
-class SplunkProcessor {
-
- private static final String FEATURE = "camel-splunk";
-
- @BuildStep
- FeatureBuildItem feature() {
- return new FeatureBuildItem(FEATURE);
- }
-
- @BuildStep
- ExtensionSslNativeSupportBuildItem activateSslNativeSupport() {
- return new ExtensionSslNativeSupportBuildItem(FEATURE);
- }
-
- @BuildStep
- RuntimeInitializedClassBuildItem runtimeInitBcryptUtil() {
- // this class uses a SecureRandom which needs to be initialised at run time
- return new RuntimeInitializedClassBuildItem(HttpService.class.getName());
- }
-
- @BuildStep
- ReflectiveClassBuildItem registerForReflection(CombinedIndexBuildItem combinedIndex) {
- IndexView index = combinedIndex.getIndex();
-
- List<String> dtos = index.getAllKnownSubclasses(DotName.createSimple(Input.class))
- .stream()
- .map(c -> c.name().toString())
- .toList();
-
- return ReflectiveClassBuildItem.builder(dtos.toArray(new String[0])).build();
- }
-
- @BuildStep
- List<ReflectiveClassBuildItem> reflectiveClasses() {
- return List.of(ReflectiveClassBuildItem.builder(Index.class.getName()).constructors().build(),
- ReflectiveClassBuildItem.builder(SavedSearch.class.getName()).constructors().build(),
- ReflectiveClassBuildItem.builder(Input.class.getName()).constructors().build(),
- ReflectiveClassBuildItem.builder(Service.class.getName()).constructors().build());
- }
-
- @BuildStep
- IndexDependencyBuildItem registerDependencyForIndex() {
- return new IndexDependencyBuildItem("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.splunk");
- }
-
- @BuildStep
- NativeImageResourceBuildItem nativeImageResources() {
- List<String> timezones = new ArrayList<>();
- for (String timezone : DateTimeZone.getAvailableIDs()) {
- String[] zoneParts = timezone.split("/");
- if (zoneParts.length == 2) {
- timezones.add(String.format("org/joda/time/tz/data/%s/%s", zoneParts[0], zoneParts[1]));
- }
- }
- return new NativeImageResourceBuildItem(timezones);
- }
-
-}
diff --git a/extensions/splunk/pom.xml b/extensions/splunk/pom.xml
deleted file mode 100644
index 9155783dbe..0000000000
--- a/extensions/splunk/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-splunk-parent</artifactId>
- <name>Camel Quarkus :: Splunk</name>
- <packaging>pom</packaging>
-
- <modules>
- <module>deployment</module>
- <module>runtime</module>
- </modules>
-</project>
diff --git a/extensions/splunk/runtime/pom.xml b/extensions/splunk/runtime/pom.xml
deleted file mode 100644
index d8f9fb55f5..0000000000
--- a/extensions/splunk/runtime/pom.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-splunk-parent</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-splunk</artifactId>
- <name>Camel Quarkus :: Splunk :: Runtime</name>
- <description>Publish or search for events in Splunk.</description>
-
- <properties>
- <camel.quarkus.jvmSince>1.8.0</camel.quarkus.jvmSince>
- <camel.quarkus.nativeSince>1.8.0</camel.quarkus.nativeSince>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-splunk</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <annotationProcessorPaths>
- <path>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-extension-processor</artifactId>
- <version>${quarkus.version}</version>
- </path>
- </annotationProcessorPaths>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/extensions/splunk/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/splunk/runtime/src/main/resources/META-INF/quarkus-extension.yaml
deleted file mode 100644
index 29ab2cb3fa..0000000000
--- a/extensions/splunk/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# 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.
-#
-
-# This is a generated file. Do not edit directly!
-# To re-generate, run the following command from the top level directory:
-#
-# mvn -N cq:update-quarkus-metadata
-#
----
-name: "Camel Splunk"
-description: "Publish or search for events in Splunk"
-metadata:
- icon-url: "https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
- sponsor: "Apache Software Foundation"
- guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/splunk.html"
- categories:
- - "integration"
- status: "deprecated"
- integrates:
- - name: "Camel"
- artifact: "org.apache.camel:camel-base"
- version: "${camel.version}"
\ No newline at end of file
diff --git a/integration-test-groups/jdbc/oracle/src/main/resources/application.properties b/integration-test-groups/jdbc/oracle/src/main/resources/application.properties
index 2cb9b825a9..a5f64fbfb9 100644
--- a/integration-test-groups/jdbc/oracle/src/main/resources/application.properties
+++ b/integration-test-groups/jdbc/oracle/src/main/resources/application.properties
@@ -21,6 +21,9 @@
quarkus.datasource.oracle.db-kind=oracle
quarkus.datasource.oracle.jdbc.max-size=8
quarkus.datasource.oracle.devservices.image-name=${oracle-debezium.container.image}
+# gvenzl/oracle-free 23.26+ may need more than the testcontainers default 60s to start under CI load.
+# 10m also keeps the Db2Container default unchanged when this property is applied to all datasources in the grouped module.
+quarkus.devservices.timeout=10m
# Testcontainers' OracleContainer hard codes a 60 second startup timeout, which the first boot of the
# Oracle Free image regularly exceeds on CI, where the other jdbc-grouped database containers are being
diff --git a/integration-tests-jvm/iec60870/pom.xml b/integration-tests-jvm/iec60870/pom.xml
deleted file mode 100644
index 97437ecfdf..0000000000
--- a/integration-tests-jvm/iec60870/pom.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-build-parent-it</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-integration-test-iec60870</artifactId>
- <name>Camel Quarkus :: Integration Tests :: IEC 60870 Client</name>
- <description>Integration tests for Camel Quarkus IEC 60870 Client extension</description>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-iec60870</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy</artifactId>
- </dependency>
-
- <!-- test dependencies -->
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.rest-assured</groupId>
- <artifactId>rest-assured</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>virtualDependencies</id>
- <activation>
- <property>
- <name>!noVirtualDependencies</name>
- </property>
- </activation>
- <dependencies>
- <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-iec60870-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
-
-</project>
diff --git a/integration-tests-jvm/iec60870/src/main/java/org/apache/camel/quarkus/component/iec60870/it/Iec60870Resource.java b/integration-tests-jvm/iec60870/src/main/java/org/apache/camel/quarkus/component/iec60870/it/Iec60870Resource.java
deleted file mode 100644
index c87dc8309f..0000000000
--- a/integration-tests-jvm/iec60870/src/main/java/org/apache/camel/quarkus/component/iec60870/it/Iec60870Resource.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.quarkus.component.iec60870.it;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.apache.camel.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/iec60870")
-@ApplicationScoped
-public class Iec60870Resource {
-
- private static final Logger LOG = Logger.getLogger(Iec60870Resource.class);
-
- private static final String COMPONENT_IEC60870_CLIENT = "iec60870-client";
- private static final String COMPONENT_IEC60870_SERVER = "iec60870-server";
- @Inject
- CamelContext context;
-
- @Path("/load/component/iec60870-client")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public Response loadComponentIec60870Client() throws Exception {
- /* This is an autogenerated test */
- if (context.getComponent(COMPONENT_IEC60870_CLIENT) != null) {
- return Response.ok().build();
- }
- LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_IEC60870_CLIENT);
- return Response.status(500, COMPONENT_IEC60870_CLIENT + " could not be loaded from the Camel context").build();
- }
-
- @Path("/load/component/iec60870-server")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public Response loadComponentIec60870Server() throws Exception {
- /* This is an autogenerated test */
- if (context.getComponent(COMPONENT_IEC60870_SERVER) != null) {
- return Response.ok().build();
- }
- LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_IEC60870_SERVER);
- return Response.status(500, COMPONENT_IEC60870_SERVER + " could not be loaded from the Camel context").build();
- }
-}
diff --git a/integration-tests-jvm/iec60870/src/test/java/org/apache/camel/quarkus/component/iec60870/it/Iec60870Test.java b/integration-tests-jvm/iec60870/src/test/java/org/apache/camel/quarkus/component/iec60870/it/Iec60870Test.java
deleted file mode 100644
index 18badf41d4..0000000000
--- a/integration-tests-jvm/iec60870/src/test/java/org/apache/camel/quarkus/component/iec60870/it/Iec60870Test.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.quarkus.component.iec60870.it;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
-
-@QuarkusTest
-class Iec60870Test {
-
- @Test
- public void loadComponentIec60870Client() {
- /* A simple autogenerated test */
- RestAssured.get("/iec60870/load/component/iec60870-client")
- .then()
- .statusCode(200);
- }
-
- @Test
- public void loadComponentIec60870Server() {
- /* A simple autogenerated test */
- RestAssured.get("/iec60870/load/component/iec60870-server")
- .then()
- .statusCode(200);
- }
-
-}
diff --git a/integration-tests-jvm/irc/pom.xml b/integration-tests-jvm/irc/pom.xml
deleted file mode 100644
index 019d4fe1ef..0000000000
--- a/integration-tests-jvm/irc/pom.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-build-parent-it</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-integration-test-irc</artifactId>
- <name>Camel Quarkus :: Integration Tests :: IRC</name>
- <description>Integration tests for Camel Quarkus IRC extension</description>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-irc</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy</artifactId>
- </dependency>
-
- <!-- test dependencies -->
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.rest-assured</groupId>
- <artifactId>rest-assured</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>virtualDependencies</id>
- <activation>
- <property>
- <name>!noVirtualDependencies</name>
- </property>
- </activation>
- <dependencies>
- <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-irc-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
-
-</project>
diff --git a/integration-tests-jvm/irc/src/main/java/org/apache/camel/quarkus/component/irc/it/IrcResource.java b/integration-tests-jvm/irc/src/main/java/org/apache/camel/quarkus/component/irc/it/IrcResource.java
deleted file mode 100644
index 1c6d6d3154..0000000000
--- a/integration-tests-jvm/irc/src/main/java/org/apache/camel/quarkus/component/irc/it/IrcResource.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.quarkus.component.irc.it;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.apache.camel.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/irc")
-@ApplicationScoped
-public class IrcResource {
-
- private static final Logger LOG = Logger.getLogger(IrcResource.class);
-
- private static final String COMPONENT_IRC = "irc";
- @Inject
- CamelContext context;
-
- @Path("/load/component/irc")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public Response loadComponentIrc() throws Exception {
- /* This is an autogenerated test */
- if (context.getComponent(COMPONENT_IRC) != null) {
- return Response.ok().build();
- }
- LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_IRC);
- return Response.status(500, COMPONENT_IRC + " could not be loaded from the Camel context").build();
- }
-}
diff --git a/integration-tests-jvm/irc/src/test/java/org/apache/camel/quarkus/component/irc/it/IrcTest.java b/integration-tests-jvm/irc/src/test/java/org/apache/camel/quarkus/component/irc/it/IrcTest.java
deleted file mode 100644
index d7e90073c7..0000000000
--- a/integration-tests-jvm/irc/src/test/java/org/apache/camel/quarkus/component/irc/it/IrcTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.quarkus.component.irc.it;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
-
-@QuarkusTest
-class IrcTest {
-
- @Test
- public void loadComponentIrc() {
- /* A simple autogenerated test */
- RestAssured.get("/irc/load/component/irc")
- .then()
- .statusCode(200);
- }
-
-}
diff --git a/integration-tests-jvm/json-patch/pom.xml b/integration-tests-jvm/json-patch/pom.xml
deleted file mode 100644
index 43b484ef23..0000000000
--- a/integration-tests-jvm/json-patch/pom.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-build-parent-it</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-integration-test-json-patch</artifactId>
- <name>Camel Quarkus :: Integration Tests :: JsonPatch</name>
- <description>Integration tests for Camel Quarkus JsonPatch extension</description>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-json-patch</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy</artifactId>
- </dependency>
-
- <!-- test dependencies -->
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.rest-assured</groupId>
- <artifactId>rest-assured</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>virtualDependencies</id>
- <activation>
- <property>
- <name>!noVirtualDependencies</name>
- </property>
- </activation>
- <dependencies>
- <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-json-patch-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
-</project>
diff --git a/integration-tests-jvm/json-patch/src/main/java/org/apache/camel/quarkus/component/json/patch/it/JsonPatchResource.java b/integration-tests-jvm/json-patch/src/main/java/org/apache/camel/quarkus/component/json/patch/it/JsonPatchResource.java
deleted file mode 100644
index 8b17f92833..0000000000
--- a/integration-tests-jvm/json-patch/src/main/java/org/apache/camel/quarkus/component/json/patch/it/JsonPatchResource.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.quarkus.component.json.patch.it;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.apache.camel.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/json-patch")
-@ApplicationScoped
-public class JsonPatchResource {
-
- private static final Logger LOG = Logger.getLogger(JsonPatchResource.class);
-
- private static final String COMPONENT_JSON_PATCH = "json-patch";
- @Inject
- CamelContext context;
-
- @Path("/load/component/json-patch")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public Response loadComponentJsonPatch() throws Exception {
- /* This is an autogenerated test */
- if (context.getComponent(COMPONENT_JSON_PATCH) != null) {
- return Response.ok().build();
- }
- LOG.warnf("Could not load [%s] from the Camel context", COMPONENT_JSON_PATCH);
- return Response.status(500, COMPONENT_JSON_PATCH + " could not be loaded from the Camel context").build();
- }
-}
diff --git a/integration-tests-jvm/json-patch/src/test/java/org/apache/camel/quarkus/component/json/patch/it/JsonPatchTest.java b/integration-tests-jvm/json-patch/src/test/java/org/apache/camel/quarkus/component/json/patch/it/JsonPatchTest.java
deleted file mode 100644
index 01ec4c1a30..0000000000
--- a/integration-tests-jvm/json-patch/src/test/java/org/apache/camel/quarkus/component/json/patch/it/JsonPatchTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.quarkus.component.json.patch.it;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
-
-@QuarkusTest
-class JsonPatchTest {
-
- @Test
- public void loadComponentJsonPatch() {
- /* A simple autogenerated test */
- RestAssured.get("/json-patch/load/component/json-patch")
- .then()
- .statusCode(200);
- }
-
-}
diff --git a/integration-tests-jvm/pom.xml b/integration-tests-jvm/pom.xml
index d38cf22d6f..c316dbb945 100644
--- a/integration-tests-jvm/pom.xml
+++ b/integration-tests-jvm/pom.xml
@@ -61,15 +61,12 @@
<module>google-functions</module>
<module>huaweicloud-smn</module>
<module>ibm-secrets-manager</module>
- <module>iec60870</module>
<module>ignite</module>
- <module>irc</module>
<module>javascript</module>
<module>jcr</module>
<module>jgroups</module>
<module>jgroups-raft</module>
<module>jooq</module>
- <module>json-patch</module>
<module>jsonapi</module>
<module>junit-test-framework</module>
<module>ldif</module>
diff --git a/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTestResource.java b/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTestResource.java
index 9f8d962376..6958f297ed 100644
--- a/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTestResource.java
+++ b/integration-tests-jvm/snmp/src/test/java/org/apache/camel/quarkus/component/snmp/it/SnmpTestResource.java
@@ -174,19 +174,22 @@ public class SnmpTestResource implements QuarkusTestResourceLifecycleManager {
}
private VariableBinding generateResponseBinding(int counter, int version, OID oid) {
- //get next test
- if (SnmpTest.GET_NEXT_OID.equals(oid)) {
- //if counter < 2 return the same oid
- if (counter < 3) {
- return new VariableBinding(SnmpTest.GET_NEXT_OID, new OctetString("" + counter));
+ //get next test: the producer walks the subtree, each request asks for the OID returned by the previous
+ //response, so the step is derived from the requested OID and the returned OIDs must increase
+ if (oid.startsWith(SnmpTest.GET_NEXT_OID)) {
+ int step = oid.size() > SnmpTest.GET_NEXT_OID.size() ? oid.last() : 0;
+ if (step < 2) {
+ return new VariableBinding(new OID(SnmpTest.GET_NEXT_OID).append(step + 1),
+ new OctetString("" + (step + 1)));
}
- if (counter == 3) {
- //else return sysDescr
- return new VariableBinding(SnmpTest.GET_NEXT_OID,
- new OctetString("My GET_NEXT Printer - response #" + counter));
+ if (step == 2) {
+ return new VariableBinding(new OID(SnmpTest.GET_NEXT_OID).append(3),
+ new OctetString("My GET_NEXT Printer - response #3"));
}
- //else do not send response
- return null;
+ //an OID outside the walked subtree ends the walk
+ OID end = new OID(SnmpTest.GET_NEXT_OID);
+ end.set(end.size() - 1, end.last() + 1);
+ return new VariableBinding(end, new OctetString("end of the GET_NEXT subtree"));
}
if (SnmpTest.POLL_OID.equals(oid)) {
diff --git a/integration-tests/avro/pom.xml b/integration-tests/avro/pom.xml
index 7865aca1bd..bcd142eb10 100644
--- a/integration-tests/avro/pom.xml
+++ b/integration-tests/avro/pom.xml
@@ -94,6 +94,7 @@
</build>
<profiles>
+ <!-- https://github.com/apache/camel-quarkus/issues/9103
<profile>
<id>native</id>
<activation>
@@ -120,7 +121,7 @@
</plugin>
</plugins>
</build>
- </profile>
+ </profile> -->
<profile>
<id>virtualDependencies</id>
<activation>
diff --git a/integration-tests/avro/src/test/java/org/apache/camel/quarkus/component/avro/it/AvroTest.java b/integration-tests/avro/src/test/java/org/apache/camel/quarkus/component/avro/it/AvroTest.java
index 0c49f13364..1c8e2c5c70 100644
--- a/integration-tests/avro/src/test/java/org/apache/camel/quarkus/component/avro/it/AvroTest.java
+++ b/integration-tests/avro/src/test/java/org/apache/camel/quarkus/component/avro/it/AvroTest.java
@@ -18,10 +18,12 @@ package org.apache.camel.quarkus.component.avro.it;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.hamcrest.Matchers.is;
+@Disabled //https://github.com/apache/camel-quarkus/issues/9103
@QuarkusTest
class AvroTest {
diff --git a/integration-tests/csimple/pom.xml b/integration-tests/csimple/pom.xml
deleted file mode 100644
index 17e62077ed..0000000000
--- a/integration-tests/csimple/pom.xml
+++ /dev/null
@@ -1,195 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-build-parent-it</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-integration-test-csimple</artifactId>
- <name>Camel Quarkus :: Integration Tests :: CSimple</name>
- <description>Integration tests for Camel Quarkus CSimple extension</description>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-csimple</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-direct</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-xml-io-dsl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-yaml-dsl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-kamelet</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-bean</artifactId>
- </dependency>
-
- <!-- test dependencies -->
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.rest-assured</groupId>
- <artifactId>rest-assured</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>native</id>
- <activation>
- <property>
- <name>native</name>
- </property>
- </activation>
- <properties>
- <quarkus.native.enabled>true</quarkus.native.enabled>
- </properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>integration-test</goal>
- <goal>verify</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>virtualDependencies</id>
- <activation>
- <property>
- <name>!noVirtualDependencies</name>
- </property>
- </activation>
- <dependencies>
- <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-bean-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-csimple-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-direct-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-kamelet-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-xml-io-dsl-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-yaml-dsl-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
-
-</project>
diff --git a/integration-tests/csimple/src/main/java/org/apache/camel/quarkus/component/csimple/it/CSimpleResource.java b/integration-tests/csimple/src/main/java/org/apache/camel/quarkus/component/csimple/it/CSimpleResource.java
deleted file mode 100644
index 9fe184d5b8..0000000000
--- a/integration-tests/csimple/src/main/java/org/apache/camel/quarkus/component/csimple/it/CSimpleResource.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.quarkus.component.csimple.it;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import org.apache.camel.ProducerTemplate;
-
-@Path("/csimple")
-@ApplicationScoped
-public class CSimpleResource {
-
- @Inject
- ProducerTemplate producerTemplate;
-
- @Path("/csimple-hello")
- @POST
- @Consumes(MediaType.TEXT_PLAIN)
- @Produces(MediaType.TEXT_PLAIN)
- public String csimpleHello(String body) {
- return producerTemplate.requestBody("direct:csimple-hello", body, String.class);
- }
-
- @GET
- @Path("/csimple-hi")
- public String hi() {
- return producerTemplate.requestBody("direct:csimple-hi", null, String.class);
- }
-
- @Path("/csimple-xml-dsl")
- @POST
- @Consumes(MediaType.TEXT_PLAIN)
- @Produces(MediaType.TEXT_PLAIN)
- public String csimpleXmlDsl(String body) {
- return producerTemplate.requestBody("direct:csimple-xml-dsl", body, String.class);
- }
-
- @Path("/csimple-yaml-dsl")
- @POST
- @Consumes(MediaType.TEXT_PLAIN)
- @Produces(MediaType.TEXT_PLAIN)
- public String csimpleYamlDsl(String body) {
- return producerTemplate.requestBody("direct:csimple-yaml-dsl", body, String.class);
- }
-
- @POST
- @Path("/predicate")
- @Consumes(MediaType.TEXT_PLAIN)
- @Produces(MediaType.TEXT_PLAIN)
- public String predicate(String message) {
- return producerTemplate.requestBody("direct:predicate", message, String.class);
- }
-}
diff --git a/integration-tests/csimple/src/main/java/org/apache/camel/quarkus/component/csimple/it/CSimpleRoute.java b/integration-tests/csimple/src/main/java/org/apache/camel/quarkus/component/csimple/it/CSimpleRoute.java
deleted file mode 100644
index 740e3a0d39..0000000000
--- a/integration-tests/csimple/src/main/java/org/apache/camel/quarkus/component/csimple/it/CSimpleRoute.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.quarkus.component.csimple.it;
-
-import io.quarkus.runtime.annotations.RegisterForReflection;
-import org.apache.camel.builder.RouteBuilder;
-
-@RegisterForReflection(targets = String.class)
-public class CSimpleRoute extends RouteBuilder {
-
- @Override
- public void configure() {
- routeTemplate("whereTo")
- .templateParameter("bar")
- .templateBean("myBar", String.class, "csimple", "Hi")
- .from("kamelet:source")
- .to("bean:{{myBar}}?method=toString")
- .setBody().csimple("${body} {{bar}}");
- from("direct:csimple-hi")
- .kamelet("whereTo?bar=Bill");
- from("direct:csimple-hello")
- .setBody().csimple("Hello ${body}");
- from("direct:predicate")
- .choice()
- .when().csimple("${body} > 10")
- .setBody().constant("High").endChoice()
- .otherwise()
- .setBody().constant("Low").endChoice();
- }
-
-}
diff --git a/integration-tests/csimple/src/main/resources/application.properties b/integration-tests/csimple/src/main/resources/application.properties
deleted file mode 100644
index 940bc7645b..0000000000
--- a/integration-tests/csimple/src/main/resources/application.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-## ---------------------------------------------------------------------------
-## 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.
-## ---------------------------------------------------------------------------
-
-camel.main.routes-include-pattern = classpath:routes/my-routes.xml,classpath:routes/my-routes.yaml
diff --git a/integration-tests/csimple/src/main/resources/routes/my-routes.xml b/integration-tests/csimple/src/main/resources/routes/my-routes.xml
deleted file mode 100644
index e6b44701ed..0000000000
--- a/integration-tests/csimple/src/main/resources/routes/my-routes.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://camel.apache.org/schema/spring"
- xmlns:foo="http://camel.apache.org/foo"
- xsi:schemaLocation="
- http://camel.apache.org/schema/spring
- http://camel.apache.org/schema/spring/camel-spring.xsd">
-
- <route id="csimple-xml-dsl">
- <from uri="direct:csimple-xml-dsl"/>
- <setBody>
- <csimple>Hi ${body}</csimple>
- </setBody>
- </route>
-
-</routes>
\ No newline at end of file
diff --git a/integration-tests/csimple/src/main/resources/routes/my-routes.yaml b/integration-tests/csimple/src/main/resources/routes/my-routes.yaml
deleted file mode 100644
index 2a71518d64..0000000000
--- a/integration-tests/csimple/src/main/resources/routes/my-routes.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# 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.
-#
-
----
-- from:
- uri: "direct:csimple-yaml-dsl"
- steps:
- - setBody:
- csimple: "Bonjour ${body}"
diff --git a/integration-tests/csimple/src/test/java/org/apache/camel/quarkus/component/csimple/it/CSimpleIT.java b/integration-tests/csimple/src/test/java/org/apache/camel/quarkus/component/csimple/it/CSimpleIT.java
deleted file mode 100644
index d4e651fb85..0000000000
--- a/integration-tests/csimple/src/test/java/org/apache/camel/quarkus/component/csimple/it/CSimpleIT.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.quarkus.component.csimple.it;
-
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-
-@QuarkusIntegrationTest
-class CSimpleIT extends CSimpleTest {
-
-}
diff --git a/integration-tests/csimple/src/test/java/org/apache/camel/quarkus/component/csimple/it/CSimpleTest.java b/integration-tests/csimple/src/test/java/org/apache/camel/quarkus/component/csimple/it/CSimpleTest.java
deleted file mode 100644
index 056c4482aa..0000000000
--- a/integration-tests/csimple/src/test/java/org/apache/camel/quarkus/component/csimple/it/CSimpleTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.quarkus.component.csimple.it;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import io.restassured.http.ContentType;
-import org.hamcrest.CoreMatchers;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.Matchers.is;
-
-@QuarkusTest
-class CSimpleTest {
-
- @Test
- void csimpleHello() {
- RestAssured.given()
- .body("Joe")
- .contentType(ContentType.TEXT)
- .post("/csimple/csimple-hello")
- .then()
- .body(is("Hello Joe"));
- }
-
- @Test
- void csimpleHi() {
- RestAssured.given()
- .get("/csimple/csimple-hi")
- .then()
- .body(is("Hi Bill"));
- }
-
- @Test
- void csimpleXml() {
- RestAssured.given()
- .body("Joe")
- .contentType(ContentType.TEXT)
- .post("/csimple/csimple-xml-dsl")
- .then()
- .body(is("Hi Joe"));
- }
-
- @Test
- void csimpleYaml() {
- RestAssured.given()
- .body("John")
- .contentType(ContentType.TEXT)
- .post("/csimple/csimple-yaml-dsl")
- .then()
- .body(is("Bonjour John"));
- }
-
- @Test
- void csimpleHigh() {
- RestAssured.given()
- .body("15")
- .post("/csimple/predicate")
- .then()
- .statusCode(200)
- .body(CoreMatchers.is("High"));
- }
-
- @Test
- void csimpleLow() {
- RestAssured.given()
- .body("3")
- .post("/csimple/predicate")
- .then()
- .statusCode(200)
- .body(CoreMatchers.is("Low"));
- }
-}
diff --git a/integration-tests/digitalocean/README.adoc b/integration-tests/digitalocean/README.adoc
deleted file mode 100644
index cf474c9601..0000000000
--- a/integration-tests/digitalocean/README.adoc
+++ /dev/null
@@ -1,14 +0,0 @@
-== Camel Quarkus Digitalocean Integration Tests
-
-By default, the Digitalocean integration tests use WireMock to stub the API interactions.
-
-To run `camel-quarkus-digitalocean` integration tests using Digitalocean API interactions, you will need a Digitalocean Token. Create a Digitalocean https://www.digitalocean.com/docs/apis-clis/api/create-personal-access-token/[Access Token].
-
-Then set the following environment variables:
-
-[source,shell]
-----
-DIGITALOCEAN_AUTH_TOKEN=your-api-token
-DIGITALOCEAN_PUBLIC_KEY=your-public-key-to-run-key-tests
-----
-
diff --git a/integration-tests/digitalocean/pom.xml b/integration-tests/digitalocean/pom.xml
deleted file mode 100644
index 365caa3666..0000000000
--- a/integration-tests/digitalocean/pom.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
- 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.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-build-parent-it</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
- </parent>
-
- <artifactId>camel-quarkus-integration-test-digitalocean</artifactId>
- <name>Camel Quarkus :: Integration Tests :: DigitalOcean</name>
- <description>Integration tests for Camel Quarkus DigitalOcean extension</description>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-digitalocean</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy-jackson</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-mock</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-direct</artifactId>
- </dependency>
-
- <!-- test dependencies -->
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.rest-assured</groupId>
- <artifactId>rest-assured</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.awaitility</groupId>
- <artifactId>awaitility</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!-- dependencies needed to mock Digitalocean API -->
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-integration-wiremock-support</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <profiles>
- <profile>
- <id>native</id>
- <activation>
- <property>
- <name>native</name>
- </property>
- </activation>
- <properties>
- <quarkus.native.enabled>true</quarkus.native.enabled>
- </properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>integration-test</goal>
- <goal>verify</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>virtualDependencies</id>
- <activation>
- <property>
- <name>!noVirtualDependencies</name>
- </property>
- </activation>
- <dependencies>
- <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-digitalocean-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-direct-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-mock-deployment</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>*</groupId>
- <artifactId>*</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- </dependencies>
- </profile>
- </profiles>
-
-</project>
diff --git a/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitalOceanClientMock.java b/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitalOceanClientMock.java
deleted file mode 100644
index 3e206d2e27..0000000000
--- a/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitalOceanClientMock.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import com.myjeeva.digitalocean.impl.DigitalOceanClient;
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.conn.routing.HttpRoute;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.impl.conn.DefaultRoutePlanner;
-import org.apache.http.impl.conn.DefaultSchemePortResolver;
-import org.apache.http.protocol.HttpContext;
-
-public class DigitalOceanClientMock extends DigitalOceanClient {
-
- public DigitalOceanClientMock(String authToken, String apiHost) {
- super(authToken);
- this.apiHost = apiHost;
- this.httpClient = HttpClients.custom()
- .setRoutePlanner(new DefaultRoutePlanner(DefaultSchemePortResolver.INSTANCE) {
- @Override
- public HttpRoute determineRoute(HttpHost host, HttpRequest request, HttpContext context)
- throws HttpException {
- // Override DigitalOceanClient forcing HTTPS
- HttpHost httpSchemeHost = new HttpHost(host.getHostName(), host.getPort(), "http");
- return super.determineRoute(httpSchemeHost, request, context);
- }
- })
- .build();
- }
-
-}
diff --git a/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanResource.java b/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanResource.java
deleted file mode 100644
index a1b61fe136..0000000000
--- a/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanResource.java
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.myjeeva.digitalocean.pojo.Account;
-import com.myjeeva.digitalocean.pojo.Action;
-import com.myjeeva.digitalocean.pojo.Backup;
-import com.myjeeva.digitalocean.pojo.Delete;
-import com.myjeeva.digitalocean.pojo.Droplet;
-import com.myjeeva.digitalocean.pojo.FloatingIP;
-import com.myjeeva.digitalocean.pojo.Image;
-import com.myjeeva.digitalocean.pojo.Key;
-import com.myjeeva.digitalocean.pojo.Region;
-import com.myjeeva.digitalocean.pojo.Size;
-import com.myjeeva.digitalocean.pojo.Snapshot;
-import com.myjeeva.digitalocean.pojo.Tag;
-import com.myjeeva.digitalocean.pojo.Volume;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.apache.camel.ProducerTemplate;
-import org.apache.camel.component.digitalocean.constants.DigitalOceanHeaders;
-import org.apache.camel.component.digitalocean.constants.DigitalOceanOperations;
-import org.jboss.logging.Logger;
-
-@SuppressWarnings("unchecked")
-@Path("digitalocean")
-@ApplicationScoped
-@Consumes(MediaType.APPLICATION_JSON)
-@Produces(MediaType.APPLICATION_JSON)
-public class DigitaloceanResource {
-
- private static final Logger LOG = Logger.getLogger(DigitaloceanResource.class);
- private static final String REGION_FRANKFURT = "fra1";
- private static final String DROPLET_SIZE_1_GB = "s-1vcpu-1gb";
- private static final String DROPLET_IMAGE = "ubuntu-20-04-x64";
- private static final List<String> DROPLET_TAGS = Arrays.asList("tag1", "tag2");
- private static final int VOLUME_SIZE_5_GB = 5;
-
- @Inject
- ProducerTemplate producerTemplate;
-
- @PUT
- @Path("droplet/{name}")
- public int createDroplet(@PathParam("name") String name) {
- LOG.infof("creating a droplet with name %s", name);
- Map<String, Object> headers = createHeaders(name);
- Droplet droplet = producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, Droplet.class);
- return droplet.getId();
- }
-
- /**
- * Creates the headers for operation `Create a Droplet`
- */
- private Map<String, Object> createHeaders(String name) {
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.create);
- headers.put(DigitalOceanHeaders.REGION, REGION_FRANKFURT);
- headers.put(DigitalOceanHeaders.DROPLET_SIZE, DROPLET_SIZE_1_GB);
- headers.put(DigitalOceanHeaders.DROPLET_IMAGE, DROPLET_IMAGE);
- headers.put(DigitalOceanHeaders.DROPLET_TAGS, DROPLET_TAGS);
- headers.put(DigitalOceanHeaders.NAME, name);
- return headers;
- }
-
- @DELETE
- @Path("droplet/{id}")
- public Response deleteDroplet(@PathParam("id") int id) {
- LOG.infof("deleting a droplet with id %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.delete);
- headers.put(DigitalOceanHeaders.ID, id);
- producerTemplate.sendBodyAndHeaders("direct:droplet", null, headers);
- return Response.accepted().build();
- }
-
- @GET
- @Path("droplet/{id}")
- public Droplet getDroplet(@PathParam("id") int id) {
- LOG.infof("getting droplet with id %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.get);
- headers.put(DigitalOceanHeaders.ID, id);
- return producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, Droplet.class);
- }
-
- @GET
- @Path("droplet/actions/{id}")
- public List<Action> getActions(@PathParam("id") int id) {
- LOG.infof("getting action's droplet with id %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.listActions);
- headers.put(DigitalOceanHeaders.ID, id);
- return producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, List.class);
- }
-
- @POST
- @Path("droplet/snapshot/{id}")
- public Action snapshotDroplet(@PathParam("id") int id, String snapshotName) {
- LOG.infof("snapshot droplet %s with name %s", id, snapshotName);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.takeSnapshot);
- headers.put(DigitalOceanHeaders.ID, id);
- headers.put(DigitalOceanHeaders.NAME, snapshotName);
- return producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, Action.class);
- }
-
- @GET
- @Path("droplet/snapshots/{id}")
- public List<Snapshot> getSnapshots(@PathParam("id") int id) {
- LOG.infof("getting snapshot's droplet with id %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.listSnapshots);
- headers.put(DigitalOceanHeaders.ID, id);
- return producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, List.class);
- }
-
- @GET
- @Path("droplet/backups/enable/{id}")
- public Action enableBackups(@PathParam("id") int id) {
- LOG.infof("Enable backups for droplet %s", id);
- return doAction(id, DigitalOceanOperations.enableBackups);
- }
-
- @GET
- @Path("droplet/backups/disable/{id}")
- public Action disableBackups(@PathParam("id") int id) {
- LOG.infof("disable backups for droplet %s", id);
- return doAction(id, DigitalOceanOperations.disableBackups);
- }
-
- @GET
- @Path("droplet/on/{id}")
- public Action turnOn(@PathParam("id") int id) {
- LOG.infof("Turn on droplet %s", id);
- return doAction(id, DigitalOceanOperations.powerOn);
- }
-
- @GET
- @Path("droplet/off/{id}")
- public Action turnOff(@PathParam("id") int id) {
- LOG.infof("Turn off droplet %s", id);
- return doAction(id, DigitalOceanOperations.powerOff);
- }
-
- @GET
- @Path("droplet/reboot/{id}")
- public Action rebootDroplet(@PathParam("id") int id) {
- LOG.infof("Reboot droplet %s", id);
- return doAction(id, DigitalOceanOperations.reboot);
- }
-
- @GET
- @Path("droplet/ipv6/{id}")
- public Action enableIpv6(@PathParam("id") int id) {
- LOG.infof("Enable Ipv6 for droplet %s", id);
- return doAction(id, DigitalOceanOperations.enableIpv6);
- }
-
- private Action doAction(int id, DigitalOceanOperations operation) {
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, operation);
- headers.put(DigitalOceanHeaders.ID, id);
- return producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, Action.class);
- }
-
- @GET
- @Path("droplet/backups/{id}")
- public List<Backup> getBackups(@PathParam("id") int id) {
- LOG.infof("getting backup's droplet with id %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.listBackups);
- headers.put(DigitalOceanHeaders.ID, id);
- return producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, List.class);
- }
-
- @GET
- @Path("droplet/neighbors/{id}")
- public List<Droplet> getNeighbors(@PathParam("id") int id) {
- LOG.infof("getting neighbor's droplet with id %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.listNeighbors);
- headers.put(DigitalOceanHeaders.ID, id);
- return producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, List.class);
- }
-
- @GET
- @Path("droplet/neighbors")
- public List<Droplet> getAllNeighbors() {
- LOG.infof("getting all neighbors");
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.listAllNeighbors);
- return producerTemplate.requestBodyAndHeaders("direct:droplet", null, headers, List.class);
- }
-
- @GET
- @Path("account")
- public Account getAccount() {
- LOG.infof("getting the account");
- return producerTemplate.requestBody("direct:account", null, Account.class);
- }
-
- @GET
- @Path("action/{id}")
- public Action getAction(@PathParam("id") Integer id) {
- LOG.infof("getting the action %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.ID, id);
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.get);
- return producerTemplate.requestBodyAndHeaders("direct:actions", null, headers, Action.class);
- }
-
- @GET
- @Path("actions")
- public List<Action> getActions() {
- LOG.infof("getting all account's actions");
- return producerTemplate.requestBodyAndHeader("direct:actions", null, DigitalOceanHeaders.OPERATION,
- DigitalOceanOperations.list, List.class);
- }
-
- @GET
- @Path("images")
- public List<Image> getImages() {
- LOG.infof("getting all account's images");
- return producerTemplate.requestBodyAndHeader("direct:images", null, DigitalOceanHeaders.OPERATION,
- DigitalOceanOperations.list, List.class);
- }
-
- @GET
- @Path("images/{id}")
- public Image getImageById(@PathParam("id") Integer id) {
- LOG.infof("getting an image by id %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.ID, id);
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.get);
- return producerTemplate.requestBodyAndHeaders("direct:images", null, headers, Image.class);
- }
-
- @GET
- @Path("images/user")
- public List<Image> getUserImages() {
- LOG.infof("getting user's images");
- return producerTemplate.requestBodyAndHeader("direct:images", null, DigitalOceanHeaders.OPERATION,
- DigitalOceanOperations.ownList, List.class);
- }
-
- @GET
- @Path("snapshots")
- public List<Snapshot> getSnapshots() {
- LOG.infof("getting all account's snapshots");
- return producerTemplate.requestBodyAndHeader("direct:snapshots", null, DigitalOceanHeaders.OPERATION,
- DigitalOceanOperations.list, List.class);
- }
-
- @GET
- @Path("snapshots/{id}")
- public Snapshot getSnapshotById(@PathParam("id") Integer id) {
- LOG.infof("getting an snapshot by id %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.ID, id);
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.get);
- return producerTemplate.requestBodyAndHeaders("direct:snapshots", null, headers, Snapshot.class);
- }
-
- @DELETE
- @Path("snapshots/{id}")
- public Response deleteSnapshot(@PathParam("id") Integer id) {
- LOG.infof("delete snapshot %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.delete);
- headers.put(DigitalOceanHeaders.ID, id);
- producerTemplate.sendBodyAndHeaders("direct:snapshots", null, headers);
- return Response.ok().build();
- }
-
- @GET
- @Path("sizes")
- public List<Size> getSizes() {
- LOG.infof("getting all available sizes");
- return producerTemplate.requestBody("direct:sizes", null, List.class);
- }
-
- @GET
- @Path("regions")
- public List<Region> getRegions() {
- LOG.infof("getting all available regions");
- return producerTemplate.requestBody("direct:regions", null, List.class);
- }
-
- @PUT
- @Path("floatingIP")
- public String createFloatingIP(Integer dropletId) {
- LOG.infof("create floating IP for droplet %s", dropletId);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.create);
- headers.put(DigitalOceanHeaders.DROPLET_ID, dropletId);
- // if pending task on droplet : API returns an exception. There should be a retry later
- try {
- FloatingIP floatingIP = producerTemplate.requestBodyAndHeaders("direct:floatingIPs", null, headers,
- FloatingIP.class);
- return floatingIP.getIp();
- } catch (Exception e) {
- LOG.errorf("Enable to create and assign Floating IP - Please retry - error message : %s" + e.getMessage());
- }
- return "";
- }
-
- @GET
- @Path("floatingIP/{id}")
- public FloatingIP getFloatingIpById(@PathParam("id") String id) {
- LOG.infof("get floating IP %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.get);
- headers.put(DigitalOceanHeaders.FLOATING_IP_ADDRESS, id);
- return producerTemplate.requestBodyAndHeaders("direct:floatingIPs", null, headers, FloatingIP.class);
- }
-
- @GET
- @Path("floatingIP")
- public List<FloatingIP> getAllFloatingIps() {
- LOG.infof("get all floating IPs");
- return producerTemplate.requestBodyAndHeader("direct:floatingIPs", null,
- DigitalOceanHeaders.OPERATION, DigitalOceanOperations.list, List.class);
- }
-
- @GET
- @Path("floatingIP/unassign/{id}")
- public Action unassignFloatingIp(@PathParam("id") String id) {
- LOG.infof("unassign floating IP %s");
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.unassign);
- headers.put(DigitalOceanHeaders.FLOATING_IP_ADDRESS, id);
- // if pending task on droplet : API returns an exception. There should be a retry later
- try {
- return producerTemplate.requestBodyAndHeaders("direct:floatingIPs", null, headers, Action.class);
- } catch (Exception e) {
- LOG.errorf("Enable to unassign Floating IP - Please retry - error message : %s" + e.getMessage());
- }
- return new Action();
- }
-
- @DELETE
- @Path("floatingIP/{id}")
- public Delete deleteFloatingIp(@PathParam("id") String id) {
- LOG.infof("delete floating IP %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.delete);
- headers.put(DigitalOceanHeaders.FLOATING_IP_ADDRESS, id);
- // if pending task on droplet : API returns an exception. There should be a retry later
- try {
- return producerTemplate.requestBodyAndHeaders("direct:floatingIPs", null, headers, Delete.class);
- } catch (Exception e) {
- LOG.errorf("Enable to delete Floating IP - Please retry - error message : %s" + e.getMessage());
- }
- return new Delete(false);
-
- }
-
- @GET
- @Path("floatingIP/actions/{id}")
- public List<Action> getFloatingIpsActions(@PathParam("id") String id) {
- LOG.infof("get all floating IPs actions %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.listActions);
- headers.put(DigitalOceanHeaders.FLOATING_IP_ADDRESS, id);
- return (List<Action>) producerTemplate.requestBodyAndHeaders("direct:floatingIPs", null, headers, List.class);
- }
-
- @PUT
- @Path("blockStorages")
- public String createVolume(String name) {
- LOG.infof("create volume for region %s with size %s named %s", REGION_FRANKFURT, VOLUME_SIZE_5_GB, name);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.create);
- headers.put(DigitalOceanHeaders.REGION, REGION_FRANKFURT);
- headers.put(DigitalOceanHeaders.VOLUME_SIZE_GIGABYTES, VOLUME_SIZE_5_GB);
- headers.put(DigitalOceanHeaders.NAME, name);
- headers.put(DigitalOceanHeaders.DESCRIPTION, "volume_" + name);
- Volume volume = producerTemplate.requestBodyAndHeaders("direct:blockStorages", null, headers, Volume.class);
- return volume.getId();
- }
-
- @GET
- @Path("blockStorages/{id}")
- public Volume getVolumeById(@PathParam("id") String volumeId) {
- LOG.infof("getting volume %s", volumeId);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.get);
- headers.put(DigitalOceanHeaders.ID, volumeId);
- headers.put(DigitalOceanHeaders.REGION, REGION_FRANKFURT);
- return producerTemplate.requestBodyAndHeaders("direct:blockStorages", null, headers, Volume.class);
- }
-
- @POST
- @Path("blockStorages/attach/{name}")
- public Action attachVolumeToDroplet(@PathParam("name") String volumeName, String dropletId) {
- LOG.infof("attach volume %s to droplet %s in region %s", volumeName, dropletId, REGION_FRANKFURT);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.attach);
- headers.put(DigitalOceanHeaders.VOLUME_NAME, volumeName);
- headers.put(DigitalOceanHeaders.DROPLET_ID, dropletId);
- headers.put(DigitalOceanHeaders.REGION, REGION_FRANKFURT);
- return producerTemplate.requestBodyAndHeaders("direct:blockStorages", null, headers, Action.class);
- }
-
- @POST
- @Path("blockStorages/detach/{name}")
- public Action detachVolumeToDroplet(@PathParam("name") String volumeName, String dropletId) {
- LOG.infof("detach volume %s to droplet %s in region %s", volumeName, dropletId, REGION_FRANKFURT);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.detach);
- headers.put(DigitalOceanHeaders.VOLUME_NAME, volumeName);
- headers.put(DigitalOceanHeaders.DROPLET_ID, dropletId);
- headers.put(DigitalOceanHeaders.REGION, REGION_FRANKFURT);
- return producerTemplate.requestBodyAndHeaders("direct:blockStorages", null, headers, Action.class);
- }
-
- @GET
- @Path("blockStorages")
- public List<Volume> getAvailableVolumes() {
- LOG.infof("get all avalaible volumes for region %s", REGION_FRANKFURT);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.list);
- headers.put(DigitalOceanHeaders.REGION, REGION_FRANKFURT);
- return producerTemplate.requestBodyAndHeaders("direct:blockStorages", null, headers, List.class);
- }
-
- @DELETE
- @Path("blockStorages")
- public Delete deleteVolume(String volumeId) {
- LOG.infof("delete volume %s", volumeId);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.delete);
- headers.put(DigitalOceanHeaders.ID, volumeId);
- return producerTemplate.requestBodyAndHeaders("direct:blockStorages", null, headers, Delete.class);
- }
-
- @PUT
- @Path("keys/{name}")
- public Integer createKey(@PathParam("name") String name, String publicKey) {
- LOG.infof("create key %s", name);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.create);
- headers.put(DigitalOceanHeaders.NAME, name);
- headers.put(DigitalOceanHeaders.KEY_PUBLIC_KEY, publicKey);
- Key key = producerTemplate.requestBodyAndHeaders("direct:keys", null, headers, Key.class);
- return key.getId();
- }
-
- @GET
- @Path("keys/{id}")
- public Key getKeyById(@PathParam("id") Integer id) {
- LOG.infof("get key %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.get);
- headers.put(DigitalOceanHeaders.ID, id);
- return producerTemplate.requestBodyAndHeaders("direct:keys", null, headers, Key.class);
- }
-
- @GET
- @Path("keys")
- public List<Key> getKeys() {
- LOG.infof("get keys");
- return producerTemplate.requestBodyAndHeader("direct:keys", null, DigitalOceanHeaders.OPERATION,
- DigitalOceanOperations.list, List.class);
- }
-
- @POST
- @Path("keys/{id}")
- public Key updateKey(@PathParam("id") Integer id, String name) {
- LOG.infof("update key %s with name %s", id, name);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.update);
- headers.put(DigitalOceanHeaders.ID, id);
- headers.put(DigitalOceanHeaders.NAME, name);
- return producerTemplate.requestBodyAndHeaders("direct:keys", null, headers, Key.class);
- }
-
- @DELETE
- @Path("keys/{id}")
- public Delete deleteKey(@PathParam("id") Integer id) {
- LOG.infof("delete key %s", id);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.delete);
- headers.put(DigitalOceanHeaders.ID, id);
- return producerTemplate.requestBodyAndHeaders("direct:keys", null, headers, Delete.class);
- }
-
- @POST
- @Path("tags/{name}")
- public Tag createTag(@PathParam("name") String name) {
- LOG.infof("create tag %s", name);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.create);
- headers.put(DigitalOceanHeaders.NAME, name);
- return producerTemplate.requestBodyAndHeaders("direct:tags", null, headers, Tag.class);
- }
-
- @GET
- @Path("tags/{name}")
- public Tag getTag(@PathParam("name") String name) {
- LOG.infof("get tag %s", name);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.get);
- headers.put(DigitalOceanHeaders.NAME, name);
- return producerTemplate.requestBodyAndHeaders("direct:tags", null, headers, Tag.class);
- }
-
- @GET
- @Path("tags")
- public List<Tag> getAllTags() {
- LOG.infof("get tags");
- return producerTemplate.requestBodyAndHeader("direct:tags", null, DigitalOceanHeaders.OPERATION,
- DigitalOceanOperations.list, List.class);
- }
-
- @DELETE
- @Path("tags/{name}")
- public Delete deleteTag(@PathParam("name") String name) {
- LOG.infof("delete tag %s", name);
- Map<String, Object> headers = new HashMap<>();
- headers.put(DigitalOceanHeaders.OPERATION, DigitalOceanOperations.delete);
- headers.put(DigitalOceanHeaders.NAME, name);
- return producerTemplate.requestBodyAndHeaders("direct:tags", null, headers, Delete.class);
- }
-}
diff --git a/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanRoute.java b/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanRoute.java
deleted file mode 100644
index f9b357278f..0000000000
--- a/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanRoute.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import java.util.Optional;
-
-import com.myjeeva.digitalocean.impl.DigitalOceanClient;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Named;
-import org.apache.camel.builder.RouteBuilder;
-import org.eclipse.microprofile.config.ConfigProvider;
-import org.eclipse.microprofile.config.inject.ConfigProperty;
-
-@ApplicationScoped
-public class DigitaloceanRoute extends RouteBuilder {
- @ConfigProperty(name = "DIGITALOCEAN_AUTH_TOKEN", defaultValue = "NONE")
- String oAuthToken;
-
- /**
- * We need to implement some conditional configuration of the {@link DigitalOceanClient} thus we create it
- * programmatically
- *
- * @return a configured {@link DigitalOceanClient}
- */
- @Named("digitalOceanClient")
- DigitalOceanClient initDigitalOceanClient(MockApiService mockApiService) {
- Optional<String> wireMockUrl = ConfigProvider.getConfig().getOptionalValue("wiremock.url", String.class);
- if (wireMockUrl.isPresent()) {
- return mockApiService.createDigitalOceanClient(wireMockUrl.get(), oAuthToken);
- }
- return new DigitalOceanClient(oAuthToken);
- }
-
- @Override
- public void configure() throws Exception {
- from("direct:droplet")
- .toF("digitalocean:droplets?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:account")
- .toF("digitalocean:account?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:actions")
- .toF("digitalocean:actions?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:images")
- .toF("digitalocean:images?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:snapshots")
- .toF("digitalocean:snapshots?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:sizes")
- .toF("digitalocean:sizes?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:regions")
- .toF("digitalocean:regions?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:floatingIPs")
- .toF("digitalocean:floatingIPs?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:blockStorages")
- .toF("digitalocean:blockStorages?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:keys")
- .toF("digitalocean:keys?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
-
- from("direct:tags")
- .toF("digitalocean:tags?oAuthToken=%s&digitalOceanClient=#digitalOceanClient", oAuthToken);
- }
-}
diff --git a/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/MockApiService.java b/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/MockApiService.java
deleted file mode 100644
index 16efc9d423..0000000000
--- a/integration-tests/digitalocean/src/main/java/org/apache/camel/quarkus/component/digitalocean/it/MockApiService.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import com.myjeeva.digitalocean.impl.DigitalOceanClient;
-import jakarta.enterprise.context.ApplicationScoped;
-
-@ApplicationScoped
-public class MockApiService {
-
- public DigitalOceanClient createDigitalOceanClient(String wireMockUrl, String oAuthToken) {
- return new DigitalOceanClientMock(oAuthToken, getFormattedURI(wireMockUrl));
- }
-
- String getFormattedURI(String wireMockUrl) {
- return wireMockUrl.replaceAll("http://", "");
- }
-}
diff --git a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanDropletIT.java b/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanDropletIT.java
deleted file mode 100644
index ca16d3a2f8..0000000000
--- a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanDropletIT.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-
-@QuarkusIntegrationTest
-public class DigitaloceanDropletIT extends DigitaloceanDropletTest {
-}
diff --git a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanDropletTest.java b/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanDropletTest.java
deleted file mode 100644
index 3ded48e981..0000000000
--- a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanDropletTest.java
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import com.github.tomakehurst.wiremock.WireMockServer;
-import io.quarkus.test.common.QuarkusTestResource;
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import io.restassured.http.ContentType;
-import org.apache.camel.quarkus.test.wiremock.MockServer;
-import org.eclipse.microprofile.config.ConfigProvider;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import static io.restassured.RestAssured.given;
-import static org.awaitility.Awaitility.await;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@SuppressWarnings("unchecked")
-@QuarkusTest
-@QuarkusTestResource(DigitaloceanTestResource.class)
-public class DigitaloceanDropletTest {
- static final long timeout = 5;
- static TimeUnit timeoutUnit = TimeUnit.SECONDS;
- static boolean waitBlockStorageAction = false;
-
- @MockServer
- WireMockServer server;
-
- @BeforeAll
- public static void initTimeoutUnit() {
- // add timeout if not using MockServer
- // when using a Digitalocean Key, it takes at least 2 minutes to create a droplet or snapshot
- Optional<String> key = ConfigProvider.getConfig().getOptionalValue("DIGITALOCEAN_AUTH_TOKEN", String.class);
- if (key.isPresent()) {
- timeoutUnit = TimeUnit.MINUTES;
- waitBlockStorageAction = true;
- }
- }
-
- /**
- * Testing droplet producer and all tests of producers related to an existing droplet
- *
- */
- @Test
- void testDroplets() throws InterruptedException {
- // insert multiple droplets
- Integer dropletId = RestAssured.given().contentType(ContentType.JSON).put("/digitalocean/droplet/droplet1")
- .then().extract().body().as(Integer.class);
- assertNotNull(dropletId);
-
- // get the droplet by dropletId1 until its status is active and ready
- // it takes time only if using a oAuthToken from Digitalocean
- waitActiveDroplet(dropletId);
-
- // test actions on droplet
- performActions(dropletId);
-
- // test actions
- testResultActions(dropletId);
-
- // test neighbors
- testNeighbors(dropletId);
-
- // test floating IP
- testFloatingIP(dropletId);
-
- // test images
- testImages();
-
- // test snapshots
- testSnapshots();
-
- // test block storages
- testBlockStorages(dropletId);
-
- // delete the droplet with id droplet 1
- given()
- .when()
- .delete("/digitalocean/droplet/" + dropletId)
- .then()
- .statusCode(202);
- }
-
- private void performActions(Integer dropletId) {
- // action : enable backups
- given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/droplet/backups/enable/" + dropletId)
- .then()
- .body("resourceId", equalTo(dropletId))
- .body("type", equalTo("ENABLE_BACKUPS"));
-
- // action : power off, before taking a snapshot
- given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/droplet/off/" + dropletId)
- .then()
- .body("resourceId", equalTo(dropletId));
-
- // take a snapshot
- given()
- .contentType(ContentType.JSON)
- .body("snapshot1")
- .post("/digitalocean/droplet/snapshot/" + dropletId)
- .then()
- .body("resourceId", equalTo(dropletId));
-
- waitForSnapshot(dropletId);
-
- // action : disable backups
- given()
- .when()
- .get("/digitalocean/droplet/backups/disable/" + dropletId)
- .then()
- .body("resourceId", equalTo(dropletId));
-
- // action : power on
- given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/droplet/on/" + dropletId)
- .then()
- .body("resourceId", equalTo(dropletId));
-
- // Reboot droplet
- given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/droplet/reboot/" + dropletId)
- .then()
- .body("resourceId", equalTo(dropletId));
-
- // enable Ipv6
- given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/droplet/ipv6/" + dropletId)
- .then()
- .body("resourceId", equalTo(dropletId));
- }
-
- /**
- * Test the result of actions performed
- *
- */
- private void testResultActions(Integer dropletId) {
- // getting the droplet actions
- List<Map<String, Object>> actions = RestAssured.given().contentType(ContentType.JSON)
- .get("/digitalocean/droplet/actions/" + dropletId)
- .then().extract().body().as(List.class);
- List<String> types = Arrays.asList("ENABLE_BACKUPS", "DISABLE_BACKUPS", "SNAPSHOT", "POWER_ON", "POWER_OFF", "REBOOT",
- "ENABLE_IPV6");
- assertActions(actions, types);
-
- // getting the snapshot action id
- Integer snapshotActionId = getSnapshotActionId(actions);
-
- // getting one action
- given()
- .get("/digitalocean/action/" + snapshotActionId)
- .then()
- .body("id", equalTo(snapshotActionId));
-
- // getting all actions on the account
- actions = RestAssured.given().contentType(ContentType.JSON)
- .get("/digitalocean/actions/")
- .then().extract().body().as(List.class);
- types = Arrays.asList("ENABLE_BACKUPS", "DISABLE_BACKUPS", "SNAPSHOT", "POWER_ON", "POWER_OFF", "REBOOT");
- assertActions(actions, types);
- }
-
- /**
- * Gets the snapshots and waits until the snapshot is created in Digitalocean.
- *
- */
- private void waitForSnapshot(Integer dropletId) {
- await().atMost(timeout, timeoutUnit).until(() -> {
- String path = "/digitalocean/droplet/snapshots/" + dropletId;
- List<Map<String, Object>> result = given().when().get(path).then().extract().as(List.class);
- // Look for the snapshot
- Optional<Map<String, Object>> optional = result.stream()
- .filter(s -> "snapshot1".equals(s.get("name")))
- .findAny();
- return optional.isPresent();
- });
- }
-
- /**
- * Gets the droplet and waits until the droplet is Active in Digitalocean.
- *
- */
- private void waitActiveDroplet(Integer dropletId) {
- await().atMost(timeout, timeoutUnit).until(() -> {
- String path = "/digitalocean/droplet/" + dropletId;
- Map<String, Object> droplet = given()
- .contentType(ContentType.JSON).get(path).then().extract().as(Map.class);
- return droplet != null && dropletId.equals(droplet.get("id")) && "ACTIVE".equals(droplet.get("status"));
- });
- }
-
- /**
- * Assert all the actions
- *
- */
- private void assertActions(List<Map<String, Object>> actions, List<String> types) {
- // verify there are actions
- assertNotNull(actions);
- // verify there are at least the 7 created actions in the test
- assertTrue(actions.size() >= types.size());
- types.forEach(type -> assertAction(actions, type));
- }
-
- /**
- * assert a single action
- *
- */
- private void assertAction(List<Map<String, Object>> actions, String actionType) {
- Optional<Map<String, Object>> optional = actions.stream()
- .filter(a -> actionType.equals(a.get("type")))
- .findAny();
- assertTrue(optional.isPresent());
- }
-
- /**
- * Get action of type SNAPSHOT
- *
- */
- private Integer getSnapshotActionId(List<Map<String, Object>> actions) {
- return actions.stream()
- .filter(a -> "SNAPSHOT".equals(a.get("type")))
- .findAny()
- .map(b -> (Integer) b.get("id"))
- .orElse(null);
- }
-
- private void testNeighbors(int dropletId) {
- given()
- .when()
- .get("/digitalocean/droplet/neighbors/" + dropletId)
- .then()
- .statusCode(200);
- }
-
- private void testImages() {
- // getting all images
- List<Map<String, Object>> images = RestAssured.given().contentType(ContentType.JSON)
- .get("/digitalocean/images")
- .then().extract().body().as(List.class);
- // there's at least the image created for the backup
- assertNotNull(images);
-
- // get one image id
- Integer imageId = images.stream().findAny().map(image -> (Integer) image.get("id")).orElse(null);
- assertNotNull(imageId);
-
- // get the image with id
- given().contentType(ContentType.JSON)
- .get("/digitalocean/images/" + imageId)
- .then()
- .body("id", equalTo(imageId));
-
- // test user's images
- images = RestAssured.given().contentType(ContentType.JSON)
- .get("/digitalocean/images/user")
- .then().extract().body().as(List.class);
- assertNotNull(images);
- }
-
- private void testSnapshots() {
- // getting all snapshots
- List<Map<String, Object>> images = RestAssured.given().contentType(ContentType.JSON)
- .get("/digitalocean/snapshots")
- .then().extract().body().as(List.class);
- // there's at least the image created for the backup
- assertNotNull(images);
-
- // get one snapshot id
- Integer snapshotId = images.stream().findAny().map(snapshot -> (Integer) snapshot.get("id")).orElse(null);
- assertNotNull(snapshotId);
-
- // get the snapshot with id
- given().contentType(ContentType.JSON)
- .get("/digitalocean/snapshots/" + snapshotId)
- .then()
- .body("id", equalTo(snapshotId));
-
- // delete snapshot
- given().contentType(ContentType.JSON)
- .delete("/digitalocean/snapshots/" + snapshotId)
- .then()
- .statusCode(200);
- }
-
- private void testFloatingIP(Integer dropletId) {
- AtomicReference<String> floatingIp = new AtomicReference<>();
- // create a floating IP for the droplet
- await().atMost(timeout, timeoutUnit).until(() -> {
- floatingIp.set(given().contentType(ContentType.JSON)
- .body(dropletId)
- .put("/digitalocean/floatingIP")
- .then().extract().body().asString());
- return !floatingIp.get().equals("");
- });
-
- // gets the floating IP
- given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/floatingIP/" + floatingIp)
- .then()
- .body("ip", equalTo(floatingIp.get()));
-
- // gets all the floating IP
- List<Map<String, Object>> floatingIps = given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/floatingIP")
- .then().extract().body().as(List.class);
- Optional<Map<String, Object>> floatingIpResult = floatingIps.stream()
- .filter(f -> floatingIp.get().equals(f.get("ip")))
- .findAny();
- assertTrue(floatingIpResult.isPresent());
-
- // unassign a floating IP
- final Map<String, Object>[] action = new Map[1];
- await().atMost(timeout, timeoutUnit).until(() -> {
- action[0] = given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/floatingIP/unassign/" + floatingIp)
- .then().extract().body().as(Map.class);
- return action[0] != null && "UNASSIGN_FLOATING_IP".equals(action[0].get("type"));
- });
- Integer actionId = (Integer) action[0].get("id");
-
- // get all action of a floating IP
- List<Map<String, Object>> actions = given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/floatingIP/actions/" + floatingIp)
- .then().extract().body().as(List.class);
- assertNotNull(actions);
- Optional<Map<String, Object>> actionUnassign = actions.stream()
- .filter(a -> actionId.equals(a.get("id")))
- .findAny();
- assertTrue(actionUnassign.isPresent());
-
- // delete a floating ip
- await().atMost(timeout, timeoutUnit).until(() -> {
- Map<String, Object> delete = given()
- .contentType(ContentType.JSON)
- .delete("/digitalocean/floatingIP/" + floatingIp)
- .then().extract().body().as(Map.class);
- return delete != null && (Boolean) delete.get("isRequestSuccess");
- });
- }
-
- private void testBlockStorages(Integer dropletId) throws InterruptedException {
- // create a volume
- String volumeId = given()
- .contentType(ContentType.JSON)
- .body("volume1")
- .when()
- .put("/digitalocean/blockStorages")
- .then().extract().body().asString();
- assertNotNull(volumeId);
-
- // get the volume
- given()
- .get("/digitalocean/blockStorages/" + volumeId)
- .then()
- .body("name", equalTo("volume1"));
-
- // get all volumes in the region FRA1
- List<Map<String, Object>> volumes = given()
- .get("/digitalocean/blockStorages")
- .then()
- .extract().body().as(List.class);
- assertNotNull(volumes);
- Map<String, Object> expectedResult = volumes.stream()
- .filter(v -> "volume1".equals(v.get("name")))
- .findAny().orElse(null);
- assertNotNull(expectedResult);
-
- // attach to droplet
- given()
- .contentType(ContentType.JSON)
- .body(dropletId)
- .when()
- .post("/digitalocean/blockStorages/attach/volume1")
- .then()
- .body("type", equalTo("ATTACH"));
-
- // wait until the volume is attached : or else it's impossible to detach
- waitAttachedVolume(dropletId, volumeId);
-
- // detach from droplet
- given()
- .contentType(ContentType.JSON)
- .body(dropletId)
- .when()
- .post("/digitalocean/blockStorages/detach/volume1")
- .then()
- .statusCode(200);
-
- // wait until detach action is performed :: only when using digitalocean
- // if the volume is droped before being detached, there's an error in delete action, and it will be impossible to get the drop result
- if (waitBlockStorageAction) {
- Thread.sleep(10000);
- }
-
- // drop the volume
- given()
- .contentType(ContentType.JSON)
- .body(volumeId)
- .when()
- .delete("/digitalocean/blockStorages")
- .then()
- .body("isRequestSuccess", equalTo(true));
-
- }
-
- /**
- * Gets the droplet and waits until the volume is attached to the droplet
- *
- */
- private void waitAttachedVolume(Integer dropletId, String volumeId) {
- await().atMost(timeout, timeoutUnit).until(() -> {
- String path = "/digitalocean/droplet/" + dropletId;
- Map<String, Object> droplet = given()
- .contentType(ContentType.JSON).get(path).then().extract().as(Map.class);
- return droplet.get("volumeIds") != null && ((List<String>) droplet.get("volumeIds")).contains(volumeId);
- });
- }
-}
diff --git a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanIT.java b/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanIT.java
deleted file mode 100644
index 3c456b02f8..0000000000
--- a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanIT.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-
-@QuarkusIntegrationTest
-class DigitaloceanIT extends DigitaloceanTest {
-
-}
diff --git a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanTest.java b/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanTest.java
deleted file mode 100644
index 9bedf96348..0000000000
--- a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanTest.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
-import com.github.tomakehurst.wiremock.WireMockServer;
-import io.quarkus.test.common.QuarkusTestResource;
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import io.restassured.http.ContentType;
-import org.apache.camel.quarkus.test.wiremock.MockServer;
-import org.eclipse.microprofile.config.ConfigProvider;
-import org.hamcrest.CoreMatchers;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import static io.restassured.RestAssured.given;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@SuppressWarnings("unchecked")
-@QuarkusTest
-@QuarkusTestResource(DigitaloceanTestResource.class)
-class DigitaloceanTest {
- static String publicKey;
- @MockServer
- WireMockServer server;
-
- @BeforeAll
- public static void initPublicKey() {
- publicKey = ConfigProvider.getConfig().getOptionalValue("DIGITALOCEAN_PUBLIC_KEY", String.class).orElse(
- "ssh-rsa AEXAMPLEaC1yc2EAAAADAQABAAAAQQDDHr/jh2Jy4yALcK4JyWbVkPRaWmhck3IgCoeOO3z1e2dBowLh64QAM+Qb72pxekALga2oi4GvT+TlWNhzPH4V example");
- }
-
- @Test
- void testAccount() {
- given()
- .when()
- .get("/digitalocean/account/")
- .then()
- .body("uuid", notNullValue());
- }
-
- @Test
- void testSizes() {
- List<Map<String, Object>> sizes = RestAssured.given().contentType(ContentType.JSON)
- .get("/digitalocean/sizes")
- .then().extract().body().as(List.class);
- assertNotNull(sizes);
- Optional<Map<String, Object>> size_1Gb = sizes.stream()
- .filter(s -> "s-1vcpu-1gb".equals(s.get("slug")))
- .findFirst();
- assertTrue(size_1Gb.isPresent());
- }
-
- @Test
- void testRegions() {
- List<Map<String, Object>> regions = RestAssured.given().contentType(ContentType.JSON)
- .get("/digitalocean/regions")
- .then().extract().body().as(List.class);
- assertNotNull(regions);
- Optional<Map<String, Object>> nyc1Region = regions.stream()
- .filter(r -> "nyc1".equals(r.get("slug")))
- .findFirst();
- assertTrue(nyc1Region.isPresent());
- }
-
- @Test
- void testKeys() {
- // create a key
- String name = "TestKey1";
-
- Integer publicKeyId = given()
- .contentType(ContentType.JSON)
- .body(publicKey)
- .put("/digitalocean/keys/" + name)
- .then().extract().body().as(Integer.class);
-
- // get the key
- given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/keys/" + publicKeyId)
- .then()
- .body("id", equalTo(publicKeyId))
- .body("name", equalTo(name));
-
- // update key
- name = "updated_TestKey1";
- given()
- .contentType(ContentType.JSON)
- .body(name)
- .post("/digitalocean/keys/" + publicKeyId)
- .then()
- .body("id", equalTo(publicKeyId))
- .body("name", equalTo(name));
-
- // List keys
- List<Map<String, Object>> keys = given()
- .get("/digitalocean/keys")
- .then().extract().body().as(List.class);
- Optional<Map<String, Object>> resultKey = keys.stream()
- .filter(m -> publicKeyId.equals(m.get("id")))
- .findAny();
- assertTrue(resultKey.isPresent());
-
- // delete the key
- given()
- .delete("/digitalocean/keys/" + publicKeyId)
- .then()
- .body("isRequestSuccess", CoreMatchers.equalTo(true));
-
- }
-
- @Test
- void testTags() {
- // create a tag
- String name = "awesome";
- given()
- .contentType(ContentType.JSON)
- .post("/digitalocean/tags/" + name)
- .then()
- .body("name", equalTo(name));
-
- // get a tag
- given()
- .get("/digitalocean/tags/" + name)
- .then()
- .body("name", equalTo(name));
-
- // get all tags
- List<Map<String, Object>> tags = given()
- .contentType(ContentType.JSON)
- .get("/digitalocean/tags/")
- .then().extract().body().as(List.class);
- Optional<Map<String, Object>> resultKey = tags.stream()
- .filter(t -> name.equals(t.get("name")))
- .findAny();
- assertTrue(resultKey.isPresent());
-
- // delete the tag
- given()
- .delete("/digitalocean/tags/" + name)
- .then()
- .body("isRequestSuccess", CoreMatchers.equalTo(true));
-
- }
-}
diff --git a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanTestResource.java b/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanTestResource.java
deleted file mode 100644
index e67402e207..0000000000
--- a/integration-tests/digitalocean/src/test/java/org/apache/camel/quarkus/component/digitalocean/it/DigitaloceanTestResource.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.quarkus.component.digitalocean.it;
-
-import org.apache.camel.quarkus.test.wiremock.WireMockTestResourceLifecycleManager;
-
-public class DigitaloceanTestResource extends WireMockTestResourceLifecycleManager {
- private static final String DIGITALOCEAN_BASE_URL = "api.digitalocean.com";
- private static final String DIGITALOCEAN_AUTH_TOKEN = "DIGITALOCEAN_AUTH_TOKEN";
- private static final String DIGITALOCEAN_PUBLIC_KEY = "DIGITALOCEAN_PUBLIC_KEY";
-
- @Override
- protected String getRecordTargetBaseUrl() {
- return DIGITALOCEAN_BASE_URL;
- }
-
- @Override
- protected boolean isMockingEnabled() {
- return !envVarsPresent(DIGITALOCEAN_AUTH_TOKEN, DIGITALOCEAN_PUBLIC_KEY);
- }
-}
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/account.json b/integration-tests/digitalocean/src/test/resources/mappings/account.json
deleted file mode 100644
index 0c083a5be7..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/account.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "09aa79df-8a19-41df-8655-e414d390d6ed",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/account?per_page=25",
- "method": "GET"
- },
- "response": {
- "status": 200,
- "body": "{\"account\":{\"droplet_limit\":25,\"floating_ip_limit\":5,\"volume_limit\":10,\"email\":\"sammy@digitalocean.com\",\"uuid\":\"b6fr89dbf6d9156cace5f3c78dc9851d957381ef\",\"email_verified\":true,\"status\":\"active\",\"status_message\":\"\"}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "09aa79df-8a19-41df-8655-e414d390d6ed",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/action.json b/integration-tests/digitalocean/src/test/resources/mappings/action.json
deleted file mode 100644
index eb2d2f0ab8..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/action.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "50d1c4e3-a204-4cec-8f4f-60bbe0d0ccd3",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/actions/36805187?per_page=25",
- "method": "GET"
- },
- "response": {
- "status": 200,
- "body": "{\"action\":{\"id\":36805187,\"status\":\"completed\",\"type\":\"create\",\"started_at\":\"2014-11-14T16:29:21Z\",\"completed_at\":\"2014-11-14T16:30:06Z\",\"resource_id\":3164444,\"resource_type\":\"droplet\",\"region\":{\"name\":\"New York 3\",\"slug\":\"nyc3\",\"sizes\":[\"s-1vcpu-3gb\",\"m-1vcpu-8gb\",\"s-3vcpu-1gb\",\"s-1vcpu-2gb\",\"s-2vcpu-2gb\",\"s-2vcpu-4gb\",\"s-4vcpu-8gb\",\"s-6vcpu-16gb\",\"s-8vcpu-32gb\",\"s-12vcpu-48gb\",\"s-16vcpu-64gb\",\"s-20vcpu-96gb\",\"s- [...]
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "50d1c4e3-a204-4cec-8f4f-60bbe0d0ccd3",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/actionFloatingIp.json b/integration-tests/digitalocean/src/test/resources/mappings/actionFloatingIp.json
deleted file mode 100644
index 609998df79..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/actionFloatingIp.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "94d0e4ef-a524-40db-9484-2777428dead6",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/floating_ips/45.55.96.47/actions",
- "method": "POST"
- },
- "response": {
- "status": 200,
- "body": "{\"action\":{\"id\":68212773,\"status\":\"in-progress\",\"type\":\"unassign_ip\",\"started_at\":\"2015-10-15T17:46:15Z\",\"completed_at\":null,\"resource_id\":758603823,\"resource_type\":\"floating_ip\",\"region\":{\"name\":\"New York 3\",\"slug\":\"nyc3\",\"sizes\":[\"s-1vcpu-1gb\",\"s-1vcpu-2gb\",\"s-1vcpu-3gb\",\"s-2vcpu-2gb\",\"s-3vcpu-1gb\",\"s-2vcpu-4gb\",\"s-4vcpu-8gb\",\"s-6vcpu-16gb\",\"s-8vcpu-32gb\",\"s-12vcpu-48gb\",\"s-16vcpu-64gb\",\"s-20vcpu-96gb\",\"s-24vcpu- [...]
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "94d0e4ef-a524-40db-9484-2777428dead6",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/actions.json b/integration-tests/digitalocean/src/test/resources/mappings/actions.json
deleted file mode 100644
index db6513497d..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/actions.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "8a1bf17a-be22-41d2-8ee6-0a4632fda703",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/actions?page=1&per_page=25",
- "method": "GET"
- },
- "response": {
- "status": 200,
- "body": "{\"actions\":[{\"id\":36805187,\"status\":\"completed\",\"type\":\"snapshot\",\"started_at\":\"2014-11-14T16:37:34Z\",\"completed_at\":\"2014-11-14T16:39:32Z\",\"resource_id\":3164494,\"resource_type\":\"droplet\",\"region\":{\"name\":\"New York 3\",\"slug\":\"nyc3\",\"sizes\":[\"s-1vcpu-3gb\",\"m-1vcpu-8gb\",\"s-3vcpu-1gb\",\"s-1vcpu-2gb\",\"s-2vcpu-2gb\",\"s-2vcpu-4gb\",\"s-4vcpu-8gb\",\"s-6vcpu-16gb\",\"s-8vcpu-32gb\",\"s-12vcpu-48gb\",\"s-16vcpu-64gb\",\"s-20vcpu-96gb\", [...]
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "8a1bf17a-be22-41d2-8ee6-0a4632fda703",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/actionsBlockStorage.json b/integration-tests/digitalocean/src/test/resources/mappings/actionsBlockStorage.json
deleted file mode 100644
index 4aa233a328..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/actionsBlockStorage.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "dc1e7482-83e5-4b47-9686-f5f8d84b2dde",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/volumes/actions",
- "method": "POST"
- },
- "response": {
- "status": 200,
- "body": "{\"action\":{\"id\":72531856,\"status\":\"completed\",\"type\":\"attach_volume\",\"started_at\":\"2015-11-12T17:51:03Z\",\"completed_at\":\"2015-11-12T17:51:14Z\",\"resource_id\":null,\"resource_type\":\"volume\",\"region\":{\"name\":\"Frankfurt 1\",\"slug\":\"fra1\",\"sizes\":[\"s-1vcpu-1gb\",\"s-1vcpu-2gb\",\"s-1vcpu-3gb\",\"s-2vcpu-2gb\",\"s-3vcpu-1gb\",\"s-2vcpu-4gb\",\"s-4vcpu-8gb\",\"s-6vcpu-16gb\",\"s-8vcpu-32gb\",\"s-12vcpu-48gb\",\"s-16vcpu-64gb\",\"s-20vcpu-96gb\", [...]
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "dc1e7482-83e5-4b47-9686-f5f8d84b2dde",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/actionsDroplet.json b/integration-tests/digitalocean/src/test/resources/mappings/actionsDroplet.json
deleted file mode 100644
index 84c17feab0..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/actionsDroplet.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "c056ac5e-06de-4a59-b855-a2076af42405",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/droplets/3164494/actions?page=1&per_page=25",
- "method": "GET"
- },
- "response": {
- "status": 200,
- "body": "{\"actions\":[{\"id\":36805187,\"status\":\"completed\",\"type\":\"snapshot\",\"started_at\":\"2014-11-14T16:37:34Z\",\"completed_at\":\"2014-11-14T16:39:32Z\",\"resource_id\":3164494,\"resource_type\":\"droplet\",\"region\":{\"name\":\"New York 3\",\"slug\":\"nyc3\",\"sizes\":[\"s-1vcpu-3gb\",\"m-1vcpu-8gb\",\"s-3vcpu-1gb\",\"s-1vcpu-2gb\",\"s-2vcpu-2gb\",\"s-2vcpu-4gb\",\"s-4vcpu-8gb\",\"s-6vcpu-16gb\",\"s-8vcpu-32gb\",\"s-12vcpu-48gb\",\"s-16vcpu-64gb\",\"s-20vcpu-96gb\", [...]
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "c056ac5e-06de-4a59-b855-a2076af42405",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/backupsDroplet.json b/integration-tests/digitalocean/src/test/resources/mappings/backupsDroplet.json
deleted file mode 100644
index c9e1c51857..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/backupsDroplet.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "24dc5366-f13b-4b8d-a7fa-4aba404bc5b0",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/droplets/3164494/backups?page=1&per_page=25",
- "method": "GET"
- },
- "response": {
- "status": 200,
- "body" : "{\"backups\":[{\"id\":7622989,\"name\":\"example.com 2014-11-14\",\"distribution\":\"Ubuntu\",\"slug\":null,\"public\":false,\"regions\":[\"nyc3\"],\"created_at\":\"2014-11-14T16:07:38Z\",\"type\":\"snapshot\",\"min_disk_size\":20,\"size_gigabytes\":2.34}],\"meta\":{\"total\":1}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "24dc5366-f13b-4b8d-a7fa-4aba404bc5b0",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/createBlockStorage.json b/integration-tests/digitalocean/src/test/resources/mappings/createBlockStorage.json
deleted file mode 100644
index 5920ceeff4..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/createBlockStorage.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "66a36a87-b89a-4336-8c42-7d5cfbd22b84",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/volumes",
- "method": "POST"
- },
- "response": {
- "status": 200,
- "body" : "{\"volume\":{\"id\":\"506f78a4-e098-11e5-ad9f-000f53306ae1\",\"region\":{\"name\":\"New York 1\",\"slug\":\"nyc1\",\"sizes\":[\"s-1vcpu-1gb\",\"s-1vcpu-2gb\",\"s-1vcpu-3gb\",\"s-2vcpu-2gb\",\"s-3vcpu-1gb\",\"s-2vcpu-4gb\",\"s-4vcpu-8gb\",\"s-6vcpu-16gb\",\"s-8vcpu-32gb\",\"s-12vcpu-48gb\",\"s-16vcpu-64gb\",\"s-20vcpu-96gb\",\"s-24vcpu-128gb\",\"s-32vcpu-192gb\"],\"features\":[\"private_networking\",\"backups\",\"ipv6\",\"metadata\"],\"available\":true},\"droplet_ids\":[],\" [...]
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "66a36a87-b89a-4336-8c42-7d5cfbd22b84",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/createDroplet.json b/integration-tests/digitalocean/src/test/resources/mappings/createDroplet.json
deleted file mode 100644
index a9b080325f..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/createDroplet.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "02c20957-a348-464d-b13c-86b142f5b6fe",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/droplets",
- "method": "POST"
- },
- "response": {
- "status": 200,
- "body": "{\"droplet\":{\"id\":3164494,\"name\":\"example.com\",\"memory\":1024,\"vcpus\":1,\"disk\":25,\"locked\":true,\"status\":\"new\",\"kernel\":{\"id\":2233,\"name\":\"Ubuntu 14.04 x64 vmlinuz-3.13.0-37-generic\",\"version\":\"3.13.0-37-generic\"},\"created_at\":\"2014-11-14T16:36:31Z\",\"features\":[\"virtio\"],\"backup_ids\":[],\"snapshot_ids\":[],\"image\":{},\"volume_ids\":[],\"size\":{},\"size_slug\":\"s-1vcpu-1gb\",\"networks\":{},\"region\":{},\"tags\":[\"web\"]},\"links\ [...]
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "02c20957-a348-464d-b13c-86b142f5b6fe",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/createFloatingIp.json b/integration-tests/digitalocean/src/test/resources/mappings/createFloatingIp.json
deleted file mode 100644
index a1c40cb087..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/createFloatingIp.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "c63fd8a4-07d9-44ce-bd0e-2a37ab3c97d2",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/floating_ips",
- "method": "POST"
- },
- "response": {
- "status": 200,
- "body": "{\"floating_ip\":{\"ip\":\"45.55.96.47\",\"droplet\":null,\"region\":{\"name\":\"New York 3\",\"slug\":\"nyc3\",\"sizes\":[\"s-1vcpu-1gb\",\"s-1vcpu-2gb\",\"s-1vcpu-3gb\",\"s-2vcpu-2gb\",\"s-3vcpu-1gb\",\"s-2vcpu-4gb\",\"s-4vcpu-8gb\",\"s-6vcpu-16gb\",\"s-8vcpu-32gb\",\"s-12vcpu-48gb\",\"s-16vcpu-64gb\",\"s-20vcpu-96gb\",\"s-24vcpu-128gb\",\"s-32vcpu-192gb\"],\"features\":[\"private_networking\",\"backups\",\"ipv6\",\"metadata\"],\"available\":true},\"locked\":false},\"links [...]
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "c63fd8a4-07d9-44ce-bd0e-2a37ab3c97d2",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/createKey.json b/integration-tests/digitalocean/src/test/resources/mappings/createKey.json
deleted file mode 100644
index 9115fb30c2..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/createKey.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "d099f042-afd7-4bba-91c5-a82acb3f1cd4",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/account/keys",
- "method": "POST"
- },
- "response": {
- "status": 200,
- "body": "{\"ssh_key\":{\"id\":512190,\"fingerprint\":\"3b:16:bf:e4:8b:00:8b:b8:59:8c:a9:d3:f0:19:45:fa\",\"public_key\":\"ssh-rsa AEXAMPLEaC1yc2EAAAADAQABAAAAQQDDHr\/jh2Jy4yALcK4JyWbVkPRaWmhck3IgCoeOO3z1e2dBowLh64QAM+Qb72pxekALga2oi4GvT+TlWNhzPH4V example\",\"name\":\"TestKey1\"}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "d099f042-afd7-4bba-91c5-a82acb3f1cd4",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/createTag.json b/integration-tests/digitalocean/src/test/resources/mappings/createTag.json
deleted file mode 100644
index 0ffc4a09ee..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/createTag.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "57ea7ed9-76f9-43a0-8a79-23a45b027279",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/tags",
- "method": "POST"
- },
- "response": {
- "status": 200,
- "body": "{\"tag\":{\"name\":\"awesome\",\"resources\":{\"count\":0,\"droplets\":{\"count\":0},\"images\":{\"count\":0},\"volumes\":{\"count\":0},\"volume_snapshots\":{\"count\":0},\"databases\":{\"count\":0}}}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "57ea7ed9-76f9-43a0-8a79-23a45b027279",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/deleteBlockStorage.json b/integration-tests/digitalocean/src/test/resources/mappings/deleteBlockStorage.json
deleted file mode 100644
index 33d505810f..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/deleteBlockStorage.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "55b5a34c-92c1-4a16-a380-2bd8cb7a0144",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/volumes/506f78a4-e098-11e5-ad9f-000f53306ae1",
- "method": "DELETE"
- },
- "response": {
- "status": 204,
- "body" : "{\"delete\": {\"request_status\": true, \"status_code\": 204}, \"rate_limit\": { \"limit\": 5000, \"remaining\": 4998, \"reset\": \"2021-03-23T12:13:10+01\"}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "55b5a34c-92c1-4a16-a380-2bd8cb7a0144",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/deleteDroplet.json b/integration-tests/digitalocean/src/test/resources/mappings/deleteDroplet.json
deleted file mode 100644
index c3e5a784e8..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/deleteDroplet.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "aee26d41-5429-4469-be66-32fac68e1b52",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/droplets/3164494",
- "method": "DELETE"
- },
- "response": {
- "status": 204,
- "body" : "{\"delete\": {\"request_status\": true, \"status_code\": 204}, \"rate_limit\": { \"limit\": 5000, \"remaining\": 4998, \"reset\": \"2021-03-23T12:13:10+01\"}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "aee26d41-5429-4469-be66-32fac68e1b52",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/deleteFloatingIp.json b/integration-tests/digitalocean/src/test/resources/mappings/deleteFloatingIp.json
deleted file mode 100644
index 7b18abbfa0..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/deleteFloatingIp.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "eb65702e-3618-4295-9ec4-f588a304d153",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/floating_ips/45.55.96.47",
- "method": "DELETE"
- },
- "response": {
- "status": 204,
- "body" : "{\"delete\": {\"request_status\": true, \"status_code\": 204}, \"rate_limit\": { \"limit\": 5000, \"remaining\": 4998, \"reset\": \"2021-03-23T12:13:10+01\"}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "eb65702e-3618-4295-9ec4-f588a304d153",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/deleteKey.json b/integration-tests/digitalocean/src/test/resources/mappings/deleteKey.json
deleted file mode 100644
index 53fdecc5d3..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/deleteKey.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "874876d0-3483-4b75-b574-370011ab66bb",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/account/keys/512190",
- "method": "DELETE"
- },
- "response": {
- "status": 204,
- "body" : "{\"delete\": {\"request_status\": true, \"status_code\": 204}, \"rate_limit\": { \"limit\": 5000, \"remaining\": 4998, \"reset\": \"2021-03-23T12:13:10+01\"}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "874876d0-3483-4b75-b574-370011ab66bb",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/deleteSnapshot.json b/integration-tests/digitalocean/src/test/resources/mappings/deleteSnapshot.json
deleted file mode 100644
index 7013b98b8b..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/deleteSnapshot.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "4f39dfbe-1f02-4019-8513-9aecefba8c75",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/snapshots/6372321",
- "method": "DELETE"
- },
- "response": {
- "status": 204,
- "body" : "{\"delete\": {\"request_status\": true, \"status_code\": 204}, \"rate_limit\": { \"limit\": 5000, \"remaining\": 4998, \"reset\": \"2021-03-23T12:13:10+01\"}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
- "uuid": "4f39dfbe-1f02-4019-8513-9aecefba8c75",
- "persistent": true,
- "insertionIndex": 2
-}
\ No newline at end of file
diff --git a/integration-tests/digitalocean/src/test/resources/mappings/deleteTag.json b/integration-tests/digitalocean/src/test/resources/mappings/deleteTag.json
deleted file mode 100644
index 1a26da039b..0000000000
--- a/integration-tests/digitalocean/src/test/resources/mappings/deleteTag.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "id": "424f1adb-6e9e-4353-b911-f9326e0a69d0",
- "name": "digitalocean_api_json",
- "request": {
- "url": "/v2/tags/awesome",
- "method": "DELETE"
- },
- "response": {
- "status": 204,
- "body" : "{\"delete\": {\"request_status\": true, \"status_code\": 204}, \"rate_limit\": { \"limit\": 5000, \"remaining\": 4998, \"reset\": \"2021-03-23T12:13:10+01\"}}",
- "headers": {
- "Content-Type": "application/json; charset=UTF-8",
- "Date": "Tue, 03 Nov 2020 09:39:11 GMT",
- "Pragma": "no-cache",
- "Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
- "Cache-Control": "no-cache, must-revalidate",
- "Vary": "Accept-Language",
- "Server": "mafe",
- "X-XSS-Protection": "0",
- "X-Frame-Options": "SAMEORIGIN",
- "Server-Timing": "gfet4t7; dur=263",
- "Alt-Svc": "h3-Q050=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-T050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
- }
- },
... 14565 lines suppressed ...
(camel-quarkus) 01/04: Fixes #9142. Delegate langchain4j-ingest to the camel-langchain4j-ingest component
Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
JiriOndrusek pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 53aea877b4f671920c039f651b5377df7e5be18e
Author: Jiří Ondrušek <on...@gmail.com>
AuthorDate: Thu Sep 10 10:28:14 2026 +0000
Fixes #9142. Delegate langchain4j-ingest to the camel-langchain4j-ingest component
The extension's own engine is deleted; the routes now end in the
producer of the camel-langchain4j-ingest component introduced in Camel
4.23.0 (CAMEL-24621), while the Quarkus declaration surface (config
model, @Ingest API, validation, CDI resolution, native support) stays.
New options exposed from the component: parser (tika/docling, fixes
Behaviour changes (route ids, producer-worded missing-id failure,
IngestResult import) are documented in the migration guide; the
CamelIngestDocumentId header default stays pinned.
Verified: 30 deployment test suites, 18 JVM and 18 native integration
tests green.
Co-Authored-By: Claude Fable 5 <no...@anthropic.com>
---
docs/modules/ROOT/pages/migration-guide/4.0.0.adoc | 20 +
docs/modules/ROOT/pages/migration-guide/index.adoc | 1 +
.../reference/extensions/langchain4j-ingest.adoc | 142 +++++--
.../deployment/Langchain4jIngestProcessor.java | 104 ++++-
.../deployment/IngestBatchSizeConfigTest.java | 39 ++
.../IngestBuilderParserMissingComponentTest.java | 57 +++
.../IngestMaxDocumentSizeConfigTest.java | 39 ++
.../IngestParserComponentMissingTest.java | 43 ++
.../IngestPipelineParserValidationTest.java | 42 ++
.../ingest/deployment/IngestUnknownParserTest.java | 39 ++
.../ingest/deployment/IngestUnnamedBeansTest.java | 2 +-
extensions/langchain4j-ingest/runtime/pom.xml | 4 +
.../runtime/src/main/doc/usage.adoc | 92 ++++-
.../langchain4j/ingest/IngestBuildTimeConfig.java | 42 ++
.../ingest/IngestComponentPresence.java | 11 +
.../langchain4j/ingest/IngestPipeline.java | 79 ++++
.../ingest/IngestPipelineDefinition.java | 351 ++++++++++++++++
.../ingest/IngestPipelineRouteBuilder.java | 458 +++++++++++++++++++++
.../component/langchain4j/ingest/IngestRoutes.java | 331 +++++----------
.../langchain4j/ingest/core/IngestService.java | 95 -----
integration-tests/langchain4j-ingest/pom.xml | 45 ++
.../langchain4j/ingest/it/IngestItProducers.java | 28 ++
.../langchain4j/ingest/it/IngestResource.java | 66 ++-
.../src/main/resources/application.properties | 42 ++
.../ingest/it/IngestDoclingTestResource.java | 87 ++++
.../ingest/it/Langchain4jIngestDoclingIT.java | 24 +-
.../ingest/it/Langchain4jIngestDoclingTest.java | 59 +++
.../ingest/it/Langchain4jIngestTikaIT.java | 24 +-
.../ingest/it/Langchain4jIngestTikaTest.java | 184 +++++++++
.../src/test/resources/notice.html | 22 +
.../langchain4j-ingest/src/test/resources/pump.pdf | Bin 0 -> 850 bytes
.../src/test/resources/valve.pdf | Bin 0 -> 848 bytes
pom.xml | 1 +
poms/bom/pom.xml | 20 +
poms/bom/src/main/generated/flattened-full-pom.xml | 16 +
.../src/main/generated/flattened-reduced-pom.xml | 16 +
.../generated/flattened-reduced-verbose-pom.xml | 16 +
37 files changed, 2221 insertions(+), 420 deletions(-)
diff --git a/docs/modules/ROOT/pages/migration-guide/4.0.0.adoc b/docs/modules/ROOT/pages/migration-guide/4.0.0.adoc
new file mode 100644
index 0000000000..37f2ed4596
--- /dev/null
+++ b/docs/modules/ROOT/pages/migration-guide/4.0.0.adoc
@@ -0,0 +1,20 @@
+= Camel Quarkus 4.0.0 Migration Guide
+
+The following guide outlines how to adapt your code to changes that were made in Camel Quarkus 4.0.0.
+
+== LangChain4j Ingest extension changes
+
+=== The ingestion engine moved to the camel-langchain4j-ingest component
+
+The extension now drives the `camel-langchain4j-ingest` component instead of carrying its own implementation.
+The declaration surface is unchanged — the same `quarkus.camel.langchain4j.ingest.*` properties and the same `@Ingest` builder API — and grew new options (`parser`, `embedding-batch-size`, `document-splitter`, `max-document-size`).
+Java code reading the request-reply outcome as `IngestResult` now imports `org.apache.camel.component.langchain4j.ingest.IngestResult` — the extension's `org.apache.camel.quarkus.component.langchain4j.ingest.core.IngestResult` is gone with the engine, so this surfaces at compile time.
+
+A pipeline's route id is now `langchain4j-ingest-<pipeline-name>` rather than `camel-quarkus-langchain4j-ingest-<pipeline-name>`.
+Tooling that addresses the routes by id — JMX, the management endpoints, `camel.main.*` route policies keyed on ids — must use the new names.
+The prefix is the component's scheme name, so it follows the component.
+
+A consumer-fed delivery whose document id resolves to nothing still fails the exchange, but the message now comes from the component and names its `documentIdHeader` endpoint option instead of the `quarkus.camel.langchain4j.ingest.<name>.source.document-id` property.
+Code matching on the message text must be adjusted; matching on the exception type is unaffected.
+
+The default document-id header on consumer-fed pipelines remains `CamelIngestDocumentId` as released — the extension pins it over the component's own `CamelLangChain4jIngestDocumentId` default — so routes that set the header keep working unchanged.
diff --git a/docs/modules/ROOT/pages/migration-guide/index.adoc b/docs/modules/ROOT/pages/migration-guide/index.adoc
index 150b2340bc..e5104b1953 100644
--- a/docs/modules/ROOT/pages/migration-guide/index.adoc
+++ b/docs/modules/ROOT/pages/migration-guide/index.adoc
@@ -4,6 +4,7 @@ We do frequent releases, a release almost every month, and even though we strive
Listed here are guides on how to migrate between major versions and anything of significance to watch for when upgrading from minor versions.
+* xref:migration-guide/4.0.0.adoc[Camel Quarkus 3.40.x to Camel Quarkus 4.0.0 migration guide]
* xref:migration-guide/3.40.0.adoc[Camel Quarkus 3.39.x to Camel Quarkus 3.40.0 migration guide]
* xref:migration-guide/3.39.0.adoc[Camel Quarkus 3.38.x to Camel Quarkus 3.39.0 migration guide]
* xref:migration-guide/3.38.0.adoc[Camel Quarkus 3.36.x to Camel Quarkus 3.38.0 migration guide]
diff --git a/docs/modules/ROOT/pages/reference/extensions/langchain4j-ingest.adoc b/docs/modules/ROOT/pages/reference/extensions/langchain4j-ingest.adoc
index 451bf80f51..8c5cf20904 100644
--- a/docs/modules/ROOT/pages/reference/extensions/langchain4j-ingest.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/langchain4j-ingest.adoc
@@ -17,7 +17,7 @@ ifeval::[{doc-show-badges} == true]
[.badge-key]##JVM since##[.badge-supported]##3.39.0## [.badge-key]##Native since##[.badge-supported]##3.39.0## [.badge-key]##🧪##[.badge-unsupported]##Experimental##
endif::[]
-Declarative AI document ingestion: point a knowledge base at a folder via configuration; splitting, embedding and storing are handled under the hood
+Ingest documents into a LangChain4j EmbeddingStore: split, embed and store the message body.
[id="extensions-langchain4j-ingest-maven-coordinates"]
== Maven coordinates
@@ -42,7 +42,8 @@ endif::[]
[id="extensions-langchain4j-ingest-usage-ingesting-a-directory"]
=== Ingesting a directory
-Point a pipeline at a folder and the files in it become a knowledge base. No route, no ingestion code:
+Point a pipeline at a folder and the files in it become a knowledge base.
+No route, no ingestion code:
[source,properties]
----
@@ -51,17 +52,26 @@ quarkus.camel.langchain4j.ingest.products.embedding-store=products
quarkus.camel.langchain4j.ingest.products.embedding-model=my-model
----
-Each file is read as UTF-8 text — there is no format parsing, so convert a PDF or DOCX before it reaches the pipeline — split into overlapping segments (`max-segment-size`, `max-overlap-size`), embedded in batches and written to the store; a document is held in memory whole while it is split. `embedding-store` and `embedding-model` name CDI beans and may be omitted when the application has exactly one of each. Every segment carries `camel_ingest_pipeline` and `camel_ingest_document_id` m [...]
+Each file is read as UTF-8 text — unless a `parser` turns binary formats into text first, see below — split into overlapping segments (`max-segment-size`, `max-overlap-size`; or a `DocumentSplitter` CDI bean named by `document-splitter`, which then replaces the sizes), embedded in batches (`embedding-batch-size`, 32 by default) and written to the store; a document is held in memory whole while it is split, so `max-document-size` can cap it in characters — 0, the default, means no limit, [...]
+`embedding-store` and `embedding-model` name CDI beans and may be omitted when the application has exactly one of each.
+Every segment carries `camel_ingest_pipeline` and `camel_ingest_document_id` metadata, so retrieval can cite which document an answer came from (up to 3.39.x the keys were `camel_quarkus_pipeline` and `camel_quarkus_document_id` — see the migration guide).
+Apart from `enabled` and the `source.*` settings shown here, properties are fixed at build time.
+A pipeline declared through runtime properties alone — nothing but a `source.directory`, say — is invisible to build-time validation; its checks, including the clash with an equally named `@Ingest` pipeline, report at startup instead.
[NOTE]
====
-This experimental extension keeps no record of what it wrote: an edited document re-ingests on top of its old segments, and removing a document from the source removes nothing from the store. Replace and delete arrive with the synchronising engine in a later release. What is remembered is which documents were already ingested — the idempotent repository below.
+This experimental extension keeps no record of what it wrote: an edited document re-ingests on top of its old segments, and removing a document from the source removes nothing from the store.
+Replace and delete arrive with the synchronising engine in a later release.
+What is remembered is which documents were already ingested — the idempotent repository below.
====
[id="extensions-langchain4j-ingest-usage-the-idempotent-repository"]
=== The idempotent repository
-A directory pipeline registers what it ingested, keyed on the file's path, modification time and size: unchanged files are skipped, edited files re-ingest (their previous segments remain, see the note above). The default register is in-memory (100,000 keys) and is there for the poll loop, not for restarts: the consumer re-scans the directory on every poll, so without a register a running application would re-embed the whole directory every few seconds. A restart loses it and re-ingests t [...]
+A directory pipeline registers what it ingested, keyed on the file's path, modification time and size: unchanged files are skipped, edited files re-ingest (their previous segments remain, see the note above).
+The default register is in-memory (100,000 keys) and is there for the poll loop, not for restarts: the consumer re-scans the directory on every poll, so without a register a running application would re-embed the whole directory every few seconds.
+A restart loses it and re-ingests the directory once; a persistent repository makes restarts free.
+`source.idempotent-repository` names an `IdempotentRepository` bean to use instead:
[source,properties]
----
@@ -70,7 +80,8 @@ quarkus.camel.langchain4j.ingest.products.source.idempotent-repository=productsR
The bean can be provided three ways.
-*Auto-created*: an in-memory register (100,000 keys) is created and bound under the configured name — no bean definition needed, still lost on restart. If a bean with the name already exists, the existing bean wins:
+*Auto-created*: an in-memory register (100,000 keys) is created and bound under the configured name — no bean definition needed, still lost on restart.
+If a bean with the name already exists, the existing bean wins:
[source,properties]
----
@@ -78,7 +89,8 @@ quarkus.camel.langchain4j.ingest.products.source.idempotent-repository=productsR
quarkus.camel.langchain4j.ingest.products.source.idempotent-repository-auto-create=true
----
-*Defined in properties* through Camel's `camel.beans.` syntax — here a file-backed register that survives restarts (camel-core, no extra dependency). Use a name without dashes; Camel normalises dashed `camel.beans.` keys to camelCase:
+*Defined in properties* through Camel's `camel.beans.` syntax — here a file-backed register that survives restarts (camel-core, no extra dependency).
+Use a name without dashes; Camel normalises dashed `camel.beans.` keys to camelCase:
[source,properties]
----
@@ -89,9 +101,12 @@ camel.beans.productsRegister.cacheSize=100000
camel.beans.productsRegister.maxFileStoreSize=33554432
----
-`#class:` beans are created reflectively. For native mode the extension registers the camel-core repositories shown here and every `IdempotentRepository` implementation found in the Jandex index — application classes always, component-provided ones through their jar's index. A class from a jar without an index needs `@RegisterForReflection(targets = ...)` or a `quarkus.index-dependency.*` entry.
+`#class:` beans are created reflectively.
+For native mode the extension registers the camel-core repositories shown here and every `IdempotentRepository` implementation found in the Jandex index — application classes always, component-provided ones through their jar's index.
+A class from a jar without an index needs `@RegisterForReflection(targets = ...)` or a `quarkus.index-dependency.*` entry.
-*Defined as a CDI producer* — needed when construction takes other beans. A JDBC register also deduplicates across instances: reliably for consumer-fed pipelines keyed on the document id, for directory pipelines only when all instances see identical paths and modification times:
+*Defined as a CDI producer* — needed when construction takes other beans.
+A JDBC register also deduplicates across instances: reliably for consumer-fed pipelines keyed on the document id, for directory pipelines only when all instances see identical paths and modification times:
[source,java]
----
@@ -103,16 +118,52 @@ IdempotentRepository productsRegister(DataSource dataSource) {
More repository types — Caffeine, Infinispan, MongoDB, Cassandra, Hazelcast, Kafka and others, each provided by its component's extension — along with the pattern's details are covered in the xref:{cq-camel-components}:eips:idempotentConsumer-eip.adoc[Idempotent Consumer EIP guide].
-Sizing. An in-memory register smaller than the directory evicts keys and re-ingests those files during normal operation — hence the 100,000 default. `FileIdempotentRepository` falls back to its file store on a cache miss, so `cacheSize` is a performance setting; the correctness limit is `maxFileStoreSize`: the default of about 1 MB holds roughly 10–17 thousand of these keys, beyond it the oldest 1000 are dropped with a warning. A JDBC register has no size limit. Every edit adds a new key [...]
+Sizing.
+An in-memory register smaller than the directory evicts keys and re-ingests those files during normal operation — hence the 100,000 default.
+`FileIdempotentRepository` falls back to its file store on a cache miss, so `cacheSize` is a performance setting; the correctness limit is `maxFileStoreSize`: the default of about 1 MB holds roughly 10–17 thousand of these keys, beyond it the oldest 1000 are dropped with a warning.
+A JDBC register has no size limit.
+Every edit adds a new key and old keys are never removed, so a persistent register grows under churn until the synchronising engine arrives.
+There is no size option; size the bean.
+Use one register per pipeline — keys are source-derived, and pipelines sharing a register over the same directory skip each other's work.
-The register cannot be switched off: the consumer leaves files in place (`noop`), so without a register every poll would re-ingest the directory. To force a full re-ingest, restart (default register) or clear the persistent one. A pipeline that should consume its source — move or delete files after ingestion — uses `source.uri` (for example `file:/inbox?delete=true&idempotent=false` with `source.document-id=CamelFileName`), where all consumer options are available.
+The register cannot be switched off: the consumer leaves files in place (`noop`), so without a register every poll would re-ingest the directory.
+To force a full re-ingest, restart (default register) or clear the persistent one.
+A pipeline that should consume its source — move or delete files after ingestion — uses `source.uri` (for example `file:/inbox?delete=true&idempotent=false` with `source.document-id=CamelFileName`), where all consumer options are available.
-On a consumer-fed pipeline (`source.uri` or `@Ingest`), a configured register deduplicates deliveries by document id: a redelivered record or re-listed object ingests once, and a request-reply caller receives `skipped` instead of `ingested`. First write wins per id — an update with the same id is skipped, not replaced; streams that carry updates need a version-aware `source.document-id`. Only a delivery that wrote segments claims its id: a blank document answers `empty` and releases the [...]
+On a consumer-fed pipeline (`source.uri` or `@Ingest`), a configured register deduplicates deliveries by document id: a redelivered record or re-listed object ingests once, and a request-reply caller receives `skipped` instead of `ingested`.
+First write wins per id — an update with the same id is skipped, not replaced; streams that carry updates need a version-aware `source.document-id`.
+Only a delivery that wrote segments claims its id: a blank document answers `empty` and releases the claim, so an object created empty and populated later under the same id still ingests the content.
+With eager idempotency, a duplicate racing an in-flight first delivery is answered `skipped` even if that delivery then fails and releases the key.
+
+[id="extensions-langchain4j-ingest-usage-parsing-pdfs-and-office-documents"]
+=== Parsing PDFs and office documents
+
+Setting `parser` puts a document parser between the consumer and the splitter:
+
+[source,properties]
+----
+quarkus.camel.langchain4j.ingest.reports.source.directory=/var/data/reports
+quarkus.camel.langchain4j.ingest.reports.parser=tika
+----
+
+`tika` extracts plain text in-process with Apache Tika.
+It needs the `camel-quarkus-tika` extension, plus the Tika parser module for each format the pipeline should read — `org.apache.tika:tika-parser-pdf-module` for PDF, say.
+A format without its module parses to nothing and the document is skipped as empty (logged as a warning); so is a scanned, image-only PDF, since Tika does no OCR here.
+On a directory pipeline an empty parse still commits the file's key in the duplicate register, so the file is not retried until it changes — after adding a missing parser module, force a re-ingest (restart with the default register, or clear the persistent one).
+A consumer-fed pipeline releases the claim of an empty delivery instead.
+
+`docling` converts documents to structure-preserving markdown through a https://github.com/docling-project/docling-serve[Docling Serve] instance, OCR included.
+It needs the `camel-quarkus-docling` extension and the instance's address in `camel.component.docling.docling-serve-url`.
+
+A missing parser extension fails the build naming the artifact, the same way a missing consumer component does.
+The Java twin is `IngestPipeline.parser("tika")`, and a consumer-fed pipeline parses the same way — the payload the consumer delivers goes to the parser first.
+With a parser, `max-document-size` also rejects a raw payload larger than the cap (in bytes) before it reaches the parser, on top of capping the extracted text (in characters).
[id="extensions-langchain4j-ingest-usage-other-sources-declared-in-java"]
=== Other sources, declared in Java
-Any Camel consumer can feed a pipeline — the roughly 300 components, each with its own options and its own documentation. Such a pipeline is declared in Java with `@Ingest` and the Camel Endpoint DSL:
+Any Camel consumer can feed a pipeline — the roughly 300 components, each with its own options and its own documentation.
+Such a pipeline is declared in Java with `@Ingest` and the Camel Endpoint DSL:
[source,java]
----
@@ -124,13 +175,20 @@ IngestPipeline events() {
}
----
-Typing `dsl.` lists a factory for every component, each completing its own typed options. The method runs once at startup; it must return `IngestPipeline`, take no parameters and use a name no configured pipeline uses. `enabled=false` in configuration switches a Java-declared pipeline off. A component missing from the classpath fails at startup with an error naming the extension artifact that provides it — the DSL compiles regardless, since its factories all ship in one artifact.
+Typing `dsl.` lists a factory for every component, each completing its own typed options.
+The method runs once at startup; it must return `IngestPipeline`, take no parameters and use a name no configured pipeline uses.
+`enabled=false` in configuration switches a Java-declared pipeline off.
+A component missing from the classpath fails at startup with an error naming the extension artifact that provides it — the DSL compiles regardless, since its factories all ship in one artifact.
-Ingestion needs a stable id per document, and where it lives is the consumer's business: `documentId` names the header — the record key `CamelKafkaKey` above, `CamelAwsS3Key` for S3 — or gives a simple-language expression. Without it, the pipeline expects the `CamelLangChain4jIngestDocumentId` header — the `camel-langchain4j-ingest` component's convention; the 3.39 name `CamelIngestDocumentId` is still read as a fallback, see the migration guide — and fails the exchange when both are abs [...]
+Ingestion needs a stable id per document, and where it lives is the consumer's business: `documentId` names the header — the record key `CamelKafkaKey` above, `CamelAwsS3Key` for S3 — or gives a simple-language expression.
+Without it, the pipeline expects the `CamelIngestDocumentId` header and fails the exchange when it is absent.
+Mind each component's own defaults, too: the `aws2-s3` consumer *deletes objects after reading them* unless `deleteAfterRead(false)` is set — a knowledge base reads its source, it does not consume it.
After such a pipeline ingests a document, the exchange body is replaced with the `IngestResult`, so a request-reply caller receives the outcome of its call.
-The same pipeline can be declared purely in properties: `source.uri` takes the consumer URI as written, `source.document-id` the header name — or a simple-language expression written `+$simple{...}+`, the one form MicroProfile Config leaves untouched. The URI is fixed at build time by design — a runtime-overridable consumer URI would be arbitrary component invocation — while property placeholders inside it still resolve at startup, keeping credentials and endpoints runtime configuration. [...]
+The same pipeline can be declared purely in properties: `source.uri` takes the consumer URI as written, `source.document-id` the header name — or a simple-language expression written `+$simple{...}+`, the one form MicroProfile Config leaves untouched.
+The URI is fixed at build time by design — a runtime-overridable consumer URI would be arbitrary component invocation — while property placeholders inside it still resolve at startup, keeping credentials and endpoints runtime configuration.
+Treat runtime configuration as the trust boundary it is: the directory and the id expression decide what the process reads into an often external store.
[source,properties]
----
@@ -142,7 +200,10 @@ quarkus.camel.langchain4j.ingest.s3docs.embedding-store=products
[id="extensions-langchain4j-ingest-usage-when-ingestion-fails"]
=== When ingestion fails
-A failure while splitting, embedding or storing — a rate-limited model, an unreachable store — propagates to the consumer; there is no dead-letter channel in this increment. For a directory pipeline the file stays where it is and is retried on the next poll, because the duplicate-protection key is only committed on success — which also means a permanently failing file is retried forever, loudly. For a consumer-fed pipeline the component's own error handling applies: a request-reply calle [...]
+A failure while parsing, splitting, embedding or storing — an encrypted or corrupt document, an unreachable docling-serve, a rate-limited model, an unreachable store — propagates to the consumer; there is no dead-letter channel in this increment.
+For a directory pipeline the file stays where it is and is retried on the next poll, because the duplicate-protection key is only committed on success — which also means a permanently failing file is retried forever, loudly, on every poll: with a parser that includes a document the parser cannot read, so remove or fix such a file, or declare the pipeline with `source.uri` and the file consumer's `moveFailed` option to quarantine failures instead.
+For a consumer-fed pipeline the component's own error handling applies: a request-reply caller receives the exception, while a Kafka consumer with default settings logs the failure and commits the offset, so the record is *dropped* — and since this engine keeps no record either, nothing remembers it.
+A record whose configured `document-id` resolves to nothing (a Kafka record without a key, say) fails the same way, one exchange at a time.
[id="extensions-langchain4j-ingest-quarkus-langchain4j-bom"]
@@ -171,12 +232,8 @@ Note that the import order is paramount when using maven `dependencyManagement`.
As such, one might need to import the `langchain4j-bom` before other related Camel and Quarkus BOMs.
=== Quarkus LangChain4j support
-WARNING: At present, this extension is neither tested with nor intended to be used in conjunction with any Quarkus LangChain4j extensions.
-Consequently, both JVM and native modes may exhibit unexpected behaviour or fail to function correctly in such configurations.
-The `EmbeddingStore` and `EmbeddingModel` beans used by an ingestion pipeline are regular CDI beans, so they can be shared with Quarkus LangChain4j. This includes embedding stores configured through Quarkus LangChain4j.
-
-Combined with the xref:reference/extensions/langchain4j-embeddingstore.adoc#extensions-langchain4j-embeddingstore-usage-retrieval-augmentors-for-registeraiservice[RAG augmentor bridge], an `@RegisterAiService` interface can retrieve content from the embedding store populated by a pipeline.
+This extension is designed and tested to work together with the https://docs.quarkiverse.io/quarkus-langchain4j/dev/index.html[Quarkus LangChain4j] extensions. The `EmbeddingStore` and `EmbeddingModel` beans a pipeline writes through are ordinary CDI beans shared by both stacks — including stores declared through Quarkus LangChain4j configuration — and with the RAG augmentor bridge an `@RegisterAiService` interface answers from the store a pipeline filled, without glue code. The integrat [...]
[id="extensions-langchain4j-ingest-additional-camel-quarkus-configuration"]
@@ -198,6 +255,17 @@ resolve at startup, so credentials and endpoints remain runtime configuration.
| `string`
|
+a|icon:lock[title=Fixed at build time] [[quarkus-camel-langchain4j-ingest-pipeline-name-parser]]`link:#quarkus-camel-langchain4j-ingest-pipeline-name-parser[quarkus.camel.langchain4j.ingest."pipeline-name".parser]`
+
+How a consumed payload becomes text before it is split: `tika` extracts plain text
+from PDF, office and similar formats in-process, `docling` converts to
+structure-preserving markdown through a Docling Serve instance (configure it with
+`camel.component.docling.*`). When not set, the payload is read as text as-is. Each
+value needs its extension on the classpath: `camel-quarkus-tika` or
+`camel-quarkus-docling`.
+| `string`
+|
+
a|icon:lock[title=Fixed at build time] [[quarkus-camel-langchain4j-ingest-pipeline-name-embedding-store]]`link:#quarkus-camel-langchain4j-ingest-pipeline-name-embedding-store[quarkus.camel.langchain4j.ingest."pipeline-name".embedding-store]`
Name of the `EmbeddingStore` bean to write to. When not set, the only one present is
@@ -225,6 +293,33 @@ sentence split across a boundary retrievable from either side.
| `int`
| `50`
+a|icon:lock[title=Fixed at build time] [[quarkus-camel-langchain4j-ingest-pipeline-name-embedding-batch-size]]`link:#quarkus-camel-langchain4j-ingest-pipeline-name-embedding-batch-size[quarkus.camel.langchain4j.ingest."pipeline-name".embedding-batch-size]`
+
+How many segments are embedded per request to the embedding model. Providers with
+generous per-request limits ingest large documents faster with a bigger batch; a batch
+carries at most `embedding-batch-size` × `max-segment-size` characters, so tune the two
+together against the provider's token limits.
+| `int`
+| `32`
+
+a|icon:lock[title=Fixed at build time] [[quarkus-camel-langchain4j-ingest-pipeline-name-max-document-size]]`link:#quarkus-camel-langchain4j-ingest-pipeline-name-max-document-size[quarkus.camel.langchain4j.ingest."pipeline-name".max-document-size]`
+
+Maximum size of one document in characters, applied to the text about to be split;
+0, the default, means no limit. The pipeline holds a document in memory whole, so the
+cap is the protection against oversized — on a consumer-fed pipeline, attacker-sized —
+payloads. An oversized document fails the exchange cleanly.
+| `int`
+| `0`
+
+a|icon:lock[title=Fixed at build time] [[quarkus-camel-langchain4j-ingest-pipeline-name-document-splitter]]`link:#quarkus-camel-langchain4j-ingest-pipeline-name-document-splitter[quarkus.camel.langchain4j.ingest."pipeline-name".document-splitter]`
+
+Name of the `DocumentSplitter` bean replacing the default recursive splitting;
+`max-segment-size` and `max-overlap-size` are then ignored. Looked up by name only —
+an application may hold unrelated splitters. Segments returned without the identity
+metadata are re-stamped, so a custom splitter cannot break citation.
+| `string`
+|
+
a| [[quarkus-camel-langchain4j-ingest-pipeline-name-enabled]]`link:#quarkus-camel-langchain4j-ingest-pipeline-name-enabled[quarkus.camel.langchain4j.ingest."pipeline-name".enabled]`
Whether this pipeline starts. Useful to switch ingestion off in dev mode.
@@ -271,8 +366,7 @@ expression in the `+$simple{...}+` form — MicroProfile Config passes it throug
untouched, while a `+${...}+` in a properties file would be consumed as a config
expansion before Camel ever saw it. When not set, a pipeline reading a directory
uses the file name, and one consuming from a component uses the
-`CamelLangChain4jIngestDocumentId` header (the deprecated 3.39 name
-`CamelIngestDocumentId` is still read as a fallback).
+`CamelIngestDocumentId` header.
| `string`
|
|===
diff --git a/extensions/langchain4j-ingest/deployment/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/Langchain4jIngestProcessor.java b/extensions/langchain4j-ingest/deployment/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/Langchain4jIngestProcessor.java
index 3f1c1148ba..51bded4359 100644
--- a/extensions/langchain4j-ingest/deployment/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/Langchain4jIngestProcessor.java
+++ b/extensions/langchain4j-ingest/deployment/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/Langchain4jIngestProcessor.java
@@ -28,6 +28,7 @@ import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.arc.deployment.SyntheticBeansRuntimeInitBuildItem;
import io.quarkus.arc.deployment.ValidationPhaseBuildItem.ValidationErrorBuildItem;
+import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.Consume;
@@ -36,7 +37,11 @@ import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.FeatureBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ExcludeConfigBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceDirectoryBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedPackageBuildItem;
import io.quarkus.runtime.configuration.ConfigurationException;
import jakarta.inject.Singleton;
import org.apache.camel.quarkus.component.langchain4j.ingest.Ingest;
@@ -73,6 +78,72 @@ class Langchain4jIngestProcessor {
.build();
}
+ /**
+ * The documented PDF recipe adds {@code tika-parser-pdf-module}, which drags
+ * {@code jaxb-runtime} → {@code angus-activation} into the image. Angus' own GraalVM
+ * feature then reflects over every registered data-content handler and crashes on
+ * BouncyCastle's S/MIME handlers ({@code bcjmail}'s mailcap references
+ * {@code jakarta.mail.Part}, and jakarta.mail is not on the classpath). The feature only
+ * registers mailcap handlers, which nothing on the ingest path uses, so its registration
+ * is excluded — but only in the constellation that crashes: PDFBox present (the recipe) and
+ * jakarta.mail absent. An application that uses mail and angus for real keeps its feature.
+ *
+ * TODO: move to camel-quarkus-tika, see #9087.
+ */
+ @BuildStep
+ void excludeAngusActivationFeature(BuildProducer<ExcludeConfigBuildItem> excludeConfig) {
+ if (!QuarkusClassLoader.isClassPresentAtRuntime("org.apache.pdfbox.pdmodel.PDDocument")
+ || QuarkusClassLoader.isClassPresentAtRuntime("jakarta.mail.Part")) {
+ return;
+ }
+ excludeConfig.produce(new ExcludeConfigBuildItem("org\\.eclipse\\.angus\\.angus-activation-.*\\.jar",
+ "/META-INF/native-image/org.eclipse.angus/angus-activation/native-image.properties"));
+ }
+
+ /**
+ * The same recipe brings PDFBox itself. Native image needs its AWT-touching classes
+ * initialized at run time and its resource tree — font metrics, glyph lists, ICC profile —
+ * embedded. The camel-quarkus-pdf extension embeds the same files as a hand-listed constant;
+ * this registers the {@code org/apache/pdfbox/resources} directory wholesale instead, so the
+ * set cannot drift when a PDFBox upgrade adds or renames a resource. The runtime-init side is
+ * widened past camel-pdf to the rendering and graphics packages Tika's text extraction
+ * reaches. Produced only when PDFBox is on the classpath.
+ *
+ * TODO: move to camel-quarkus-tika (#9087) and align camel-quarkus-pdf with it (#9091).
+ */
+ @BuildStep
+ void pdfboxInNative(
+ BuildProducer<RuntimeInitializedClassBuildItem> runtimeInitialized,
+ BuildProducer<RuntimeInitializedPackageBuildItem> runtimeInitializedPackages,
+ BuildProducer<NativeImageResourceDirectoryBuildItem> nativeResourceDirectories,
+ BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
+ if (!QuarkusClassLoader.isClassPresentAtRuntime("org.apache.pdfbox.pdmodel.PDDocument")) {
+ return;
+ }
+ for (String className : new String[] {
+ "org.apache.pdfbox.pdmodel.font.PDType1Font",
+ "org.apache.pdfbox.pdmodel.PDDocument",
+ "org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler" }) {
+ runtimeInitialized.produce(new RuntimeInitializedClassBuildItem(className));
+ }
+ // text extraction reaches AWT-holding statics across the rendering and graphics trees
+ // (SoftMask's DirectColorModel, the CIE color spaces' ICC_ColorSpace), and Tika's own
+ // PDF classes embed them in enum constants (PDFParserConfig$TikaImageType wraps
+ // rendering.ImageType), so the packages are deferred wholesale rather than chasing one
+ // class at a time
+ for (String packageName : new String[] {
+ "org.apache.pdfbox.rendering",
+ "org.apache.pdfbox.pdmodel.graphics",
+ "org.apache.tika.parser.pdf" }) {
+ runtimeInitializedPackages.produce(new RuntimeInitializedPackageBuildItem(packageName));
+ }
+ reflectiveClasses.produce(ReflectiveClassBuildItem
+ .builder("org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler",
+ "org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDParentTreeValue")
+ .constructors().methods().build());
+ nativeResourceDirectories.produce(new NativeImageResourceDirectoryBuildItem("org/apache/pdfbox/resources"));
+ }
+
/**
* {@code #class:} beans are instantiated reflectively, which native mode allows only for
* registered classes: the two camel-core repositories the documentation recommends, plus
@@ -205,8 +276,9 @@ class Langchain4jIngestProcessor {
/**
* A pipeline whose consumer URI names a component that is not on the classpath stops the
- * build, naming the artifact that fixes it rather than failing at startup. Only configured URIs
- * can be checked: a builder-declared pipeline composes its URI at startup, where the pre-start
+ * build, naming the artifact that fixes it rather than failing at startup. The same goes for
+ * the {@code parser} value and its component. Only configured pipelines can be checked: a
+ * builder-declared pipeline composes its URI and parser at startup, where the pre-start
* task above applies the same hint. Component services are REGISTRY-destination, so they are
* read from the application archives directly — they never appear among the DISCOVERY
* {@code CamelServiceBuildItem}s.
@@ -222,6 +294,22 @@ class Langchain4jIngestProcessor {
.collect(Collectors.toSet());
for (Map.Entry<String, IngestBuildTimeConfig.PipelineBuildTimeConfig> entry : config.pipelines().entrySet()) {
+ String parser = entry.getValue().parser().orElse(null);
+ if (parser != null) {
+ if (!IngestPipeline.SUPPORTED_PARSERS.contains(parser)) {
+ validationErrors.produce(new ValidationErrorBuildItem(new ConfigurationException(
+ "Ingestion pipeline '" + entry.getKey() + "' sets parser '" + parser
+ + "'. Supported parsers: "
+ + IngestPipeline.SUPPORTED_PARSERS.stream().sorted()
+ .collect(Collectors.joining(", ")))));
+ } else if (!components.contains(parser)) {
+ validationErrors.produce(new ValidationErrorBuildItem(new ConfigurationException(
+ "Ingestion pipeline '" + entry.getKey() + "' parses with '" + parser
+ + "', but the Camel component '" + parser + "' is not on the classpath. "
+ + "Add the extension that provides it, e.g. org.apache.camel.quarkus:camel-quarkus-"
+ + parser)));
+ }
+ }
String uri = entry.getValue().source().uri().orElse(null);
if (uri == null) {
continue;
@@ -261,6 +349,18 @@ class Langchain4jIngestProcessor {
+ "max-overlap-size must be smaller than it (got " + pipeline.maxSegmentSize()
+ " / " + pipeline.maxOverlapSize() + ")")));
}
+
+ if (pipeline.embeddingBatchSize() < 1) {
+ validationErrors.produce(new ValidationErrorBuildItem(new ConfigurationException(
+ "Ingestion pipeline '" + entry.getKey() + "': embedding-batch-size must be positive (got "
+ + pipeline.embeddingBatchSize() + ")")));
+ }
+
+ if (pipeline.maxDocumentSize() < 0) {
+ validationErrors.produce(new ValidationErrorBuildItem(new ConfigurationException(
+ "Ingestion pipeline '" + entry.getKey() + "': max-document-size must not be negative, 0 "
+ + "meaning no limit (got " + pipeline.maxDocumentSize() + ")")));
+ }
}
}
}
diff --git a/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestBatchSizeConfigTest.java b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestBatchSizeConfigTest.java
new file mode 100644
index 0000000000..7d04ddf4e4
--- /dev/null
+++ b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestBatchSizeConfigTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.deployment;
+
+import io.quarkus.test.QuarkusExtensionTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+/** The embedding batch size is validated at build time on the configuration path. */
+class IngestBatchSizeConfigTest {
+
+ @RegisterExtension
+ static final QuarkusExtensionTest CONFIG = new QuarkusExtensionTest()
+ .withApplicationRoot(jar -> {
+ })
+ .overrideConfigKey("quarkus.camel.langchain4j.ingest.docs.embedding-batch-size", "0")
+ .assertException(t -> ValidationTestSupport.assertFailure(t,
+ "embedding-batch-size must be positive"));
+
+ @Test
+ void buildMustFail() {
+ Assertions.fail("The build was expected to fail");
+ }
+}
diff --git a/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestBuilderParserMissingComponentTest.java b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestBuilderParserMissingComponentTest.java
new file mode 100644
index 0000000000..b6c0d04082
--- /dev/null
+++ b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestBuilderParserMissingComponentTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.deployment;
+
+import io.quarkus.test.QuarkusExtensionTest;
+import jakarta.enterprise.context.ApplicationScoped;
+import org.apache.camel.quarkus.component.langchain4j.ingest.Ingest;
+import org.apache.camel.quarkus.component.langchain4j.ingest.IngestPipeline;
+import org.apache.camel.quarkus.component.langchain4j.ingest.Source;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+/**
+ * A builder-declared parser is composed at startup, out of reach of the build-time check — so a
+ * missing parser component must fail in the pre-start task with the same artifact hint.
+ */
+class IngestBuilderParserMissingComponentTest {
+
+ @RegisterExtension
+ static final QuarkusExtensionTest CONFIG = new QuarkusExtensionTest()
+ .withApplicationRoot(jar -> jar.addClasses(Pipelines.class, TestEmbeddingBeans.class))
+ .assertException(t -> ValidationTestSupport.assertFailure(t,
+ "parses with 'tika'", "component 'tika' is not on the classpath",
+ "org.apache.camel.quarkus:camel-quarkus-tika"));
+
+ @Test
+ void startMustFail() {
+ Assertions.fail("The application start was expected to fail");
+ }
+
+ @ApplicationScoped
+ public static class Pipelines {
+
+ @Ingest("docs")
+ IngestPipeline docs() {
+ return IngestPipeline.from(Source.file("target/parser-docs"))
+ .parser("tika")
+ .embeddingStore("store")
+ .embeddingModel("model");
+ }
+ }
+}
diff --git a/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestMaxDocumentSizeConfigTest.java b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestMaxDocumentSizeConfigTest.java
new file mode 100644
index 0000000000..571a0e4094
--- /dev/null
+++ b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestMaxDocumentSizeConfigTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.deployment;
+
+import io.quarkus.test.QuarkusExtensionTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+/** The document size cap is validated at build time on the configuration path. */
+class IngestMaxDocumentSizeConfigTest {
+
+ @RegisterExtension
+ static final QuarkusExtensionTest CONFIG = new QuarkusExtensionTest()
+ .withApplicationRoot(jar -> {
+ })
+ .overrideConfigKey("quarkus.camel.langchain4j.ingest.docs.max-document-size", "-1")
+ .assertException(t -> ValidationTestSupport.assertFailure(t,
+ "max-document-size must not be negative"));
+
+ @Test
+ void buildMustFail() {
+ Assertions.fail("The build was expected to fail");
+ }
+}
diff --git a/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestParserComponentMissingTest.java b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestParserComponentMissingTest.java
new file mode 100644
index 0000000000..1d047245ec
--- /dev/null
+++ b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestParserComponentMissingTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.deployment;
+
+import io.quarkus.test.QuarkusExtensionTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+/**
+ * A configured parser whose component is not on the classpath stops the build, naming the
+ * artifact that fixes it — the same treatment a missing consumer component gets.
+ */
+class IngestParserComponentMissingTest {
+
+ @RegisterExtension
+ static final QuarkusExtensionTest CONFIG = new QuarkusExtensionTest()
+ .withApplicationRoot(jar -> {
+ })
+ .overrideConfigKey("quarkus.camel.langchain4j.ingest.docs.parser", "tika")
+ .assertException(t -> ValidationTestSupport.assertFailure(t,
+ "parses with 'tika'", "component 'tika' is not on the classpath",
+ "org.apache.camel.quarkus:camel-quarkus-tika"));
+
+ @Test
+ void buildMustFail() {
+ Assertions.fail("The build was expected to fail");
+ }
+}
diff --git a/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestPipelineParserValidationTest.java b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestPipelineParserValidationTest.java
new file mode 100644
index 0000000000..f53a1a5efe
--- /dev/null
+++ b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestPipelineParserValidationTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.deployment;
+
+import org.apache.camel.quarkus.component.langchain4j.ingest.IngestPipeline;
+import org.apache.camel.quarkus.component.langchain4j.ingest.Source;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/** The builder rejects an unsupported parser eagerly, like the configuration path at build time. */
+class IngestPipelineParserValidationTest {
+
+ @Test
+ void unknownParserRejected() {
+ IngestPipeline pipeline = IngestPipeline.from(Source.file("target/docs"));
+ IllegalArgumentException e = Assertions.assertThrows(IllegalArgumentException.class,
+ () -> pipeline.parser("pdfmagic"));
+ Assertions.assertTrue(e.getMessage().contains("parser must be one of"), e.getMessage());
+ Assertions.assertTrue(e.getMessage().contains("pdfmagic"), e.getMessage());
+ }
+
+ @Test
+ void supportedParsersAccepted() {
+ for (String parser : IngestPipeline.SUPPORTED_PARSERS) {
+ IngestPipeline.from(Source.file("target/docs")).parser(parser);
+ }
+ }
+}
diff --git a/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestUnknownParserTest.java b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestUnknownParserTest.java
new file mode 100644
index 0000000000..f4e67d7af8
--- /dev/null
+++ b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestUnknownParserTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.deployment;
+
+import io.quarkus.test.QuarkusExtensionTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+/** A parser value outside the supported set stops the build naming the alternatives. */
+class IngestUnknownParserTest {
+
+ @RegisterExtension
+ static final QuarkusExtensionTest CONFIG = new QuarkusExtensionTest()
+ .withApplicationRoot(jar -> {
+ })
+ .overrideConfigKey("quarkus.camel.langchain4j.ingest.docs.parser", "pdfmagic")
+ .assertException(t -> ValidationTestSupport.assertFailure(t,
+ "sets parser 'pdfmagic'", "Supported parsers: docling, tika"));
+
+ @Test
+ void buildMustFail() {
+ Assertions.fail("The build was expected to fail");
+ }
+}
diff --git a/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestUnnamedBeansTest.java b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestUnnamedBeansTest.java
index 219829bca4..0bc6f94b10 100644
--- a/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestUnnamedBeansTest.java
+++ b/extensions/langchain4j-ingest/deployment/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/deployment/IngestUnnamedBeansTest.java
@@ -55,7 +55,7 @@ class IngestUnnamedBeansTest {
@Test
void unnamedStoreAndModelResolve() {
- Assertions.assertNotNull(context.getRoute("camel-quarkus-langchain4j-ingest-docs"),
+ Assertions.assertNotNull(context.getRoute("langchain4j-ingest-docs"),
"the pipeline must start with the only store and model beans, unnamed");
}
diff --git a/extensions/langchain4j-ingest/runtime/pom.xml b/extensions/langchain4j-ingest/runtime/pom.xml
index ee6af81a80..a03f1b28a5 100644
--- a/extensions/langchain4j-ingest/runtime/pom.xml
+++ b/extensions/langchain4j-ingest/runtime/pom.xml
@@ -41,6 +41,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-core</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-langchain4j-ingest</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-file</artifactId>
diff --git a/extensions/langchain4j-ingest/runtime/src/main/doc/usage.adoc b/extensions/langchain4j-ingest/runtime/src/main/doc/usage.adoc
index 3eb73506ca..5cdcdd6b33 100644
--- a/extensions/langchain4j-ingest/runtime/src/main/doc/usage.adoc
+++ b/extensions/langchain4j-ingest/runtime/src/main/doc/usage.adoc
@@ -1,6 +1,7 @@
=== Ingesting a directory
-Point a pipeline at a folder and the files in it become a knowledge base. No route, no ingestion code:
+Point a pipeline at a folder and the files in it become a knowledge base.
+No route, no ingestion code:
[source,properties]
----
@@ -9,16 +10,25 @@ quarkus.camel.langchain4j.ingest.products.embedding-store=products
quarkus.camel.langchain4j.ingest.products.embedding-model=my-model
----
-Each file is read as UTF-8 text — there is no format parsing, so convert a PDF or DOCX before it reaches the pipeline — split into overlapping segments (`max-segment-size`, `max-overlap-size`), embedded in batches and written to the store; a document is held in memory whole while it is split. `embedding-store` and `embedding-model` name CDI beans and may be omitted when the application has exactly one of each. Every segment carries `camel_ingest_pipeline` and `camel_ingest_document_id` m [...]
+Each file is read as UTF-8 text — unless a `parser` turns binary formats into text first, see below — split into overlapping segments (`max-segment-size`, `max-overlap-size`; or a `DocumentSplitter` CDI bean named by `document-splitter`, which then replaces the sizes), embedded in batches (`embedding-batch-size`, 32 by default) and written to the store; a document is held in memory whole while it is split, so `max-document-size` can cap it in characters — 0, the default, means no limit, [...]
+`embedding-store` and `embedding-model` name CDI beans and may be omitted when the application has exactly one of each.
+Every segment carries `camel_ingest_pipeline` and `camel_ingest_document_id` metadata, so retrieval can cite which document an answer came from (up to 3.39.x the keys were `camel_quarkus_pipeline` and `camel_quarkus_document_id` — see the migration guide).
+Apart from `enabled` and the `source.*` settings shown here, properties are fixed at build time.
+A pipeline declared through runtime properties alone — nothing but a `source.directory`, say — is invisible to build-time validation; its checks, including the clash with an equally named `@Ingest` pipeline, report at startup instead.
[NOTE]
====
-This experimental extension keeps no record of what it wrote: an edited document re-ingests on top of its old segments, and removing a document from the source removes nothing from the store. Replace and delete arrive with the synchronising engine in a later release. What is remembered is which documents were already ingested — the idempotent repository below.
+This experimental extension keeps no record of what it wrote: an edited document re-ingests on top of its old segments, and removing a document from the source removes nothing from the store.
+Replace and delete arrive with the synchronising engine in a later release.
+What is remembered is which documents were already ingested — the idempotent repository below.
====
=== The idempotent repository
-A directory pipeline registers what it ingested, keyed on the file's path, modification time and size: unchanged files are skipped, edited files re-ingest (their previous segments remain, see the note above). The default register is in-memory (100,000 keys) and is there for the poll loop, not for restarts: the consumer re-scans the directory on every poll, so without a register a running application would re-embed the whole directory every few seconds. A restart loses it and re-ingests t [...]
+A directory pipeline registers what it ingested, keyed on the file's path, modification time and size: unchanged files are skipped, edited files re-ingest (their previous segments remain, see the note above).
+The default register is in-memory (100,000 keys) and is there for the poll loop, not for restarts: the consumer re-scans the directory on every poll, so without a register a running application would re-embed the whole directory every few seconds.
+A restart loses it and re-ingests the directory once; a persistent repository makes restarts free.
+`source.idempotent-repository` names an `IdempotentRepository` bean to use instead:
[source,properties]
----
@@ -27,7 +37,8 @@ quarkus.camel.langchain4j.ingest.products.source.idempotent-repository=productsR
The bean can be provided three ways.
-*Auto-created*: an in-memory register (100,000 keys) is created and bound under the configured name — no bean definition needed, still lost on restart. If a bean with the name already exists, the existing bean wins:
+*Auto-created*: an in-memory register (100,000 keys) is created and bound under the configured name — no bean definition needed, still lost on restart.
+If a bean with the name already exists, the existing bean wins:
[source,properties]
----
@@ -35,7 +46,8 @@ quarkus.camel.langchain4j.ingest.products.source.idempotent-repository=productsR
quarkus.camel.langchain4j.ingest.products.source.idempotent-repository-auto-create=true
----
-*Defined in properties* through Camel's `camel.beans.` syntax — here a file-backed register that survives restarts (camel-core, no extra dependency). Use a name without dashes; Camel normalises dashed `camel.beans.` keys to camelCase:
+*Defined in properties* through Camel's `camel.beans.` syntax — here a file-backed register that survives restarts (camel-core, no extra dependency).
+Use a name without dashes; Camel normalises dashed `camel.beans.` keys to camelCase:
[source,properties]
----
@@ -46,9 +58,12 @@ camel.beans.productsRegister.cacheSize=100000
camel.beans.productsRegister.maxFileStoreSize=33554432
----
-`#class:` beans are created reflectively. For native mode the extension registers the camel-core repositories shown here and every `IdempotentRepository` implementation found in the Jandex index — application classes always, component-provided ones through their jar's index. A class from a jar without an index needs `@RegisterForReflection(targets = ...)` or a `quarkus.index-dependency.*` entry.
+`#class:` beans are created reflectively.
+For native mode the extension registers the camel-core repositories shown here and every `IdempotentRepository` implementation found in the Jandex index — application classes always, component-provided ones through their jar's index.
+A class from a jar without an index needs `@RegisterForReflection(targets = ...)` or a `quarkus.index-dependency.*` entry.
-*Defined as a CDI producer* — needed when construction takes other beans. A JDBC register also deduplicates across instances: reliably for consumer-fed pipelines keyed on the document id, for directory pipelines only when all instances see identical paths and modification times:
+*Defined as a CDI producer* — needed when construction takes other beans.
+A JDBC register also deduplicates across instances: reliably for consumer-fed pipelines keyed on the document id, for directory pipelines only when all instances see identical paths and modification times:
[source,java]
----
@@ -60,15 +75,50 @@ IdempotentRepository productsRegister(DataSource dataSource) {
More repository types — Caffeine, Infinispan, MongoDB, Cassandra, Hazelcast, Kafka and others, each provided by its component's extension — along with the pattern's details are covered in the xref:{cq-camel-components}:eips:idempotentConsumer-eip.adoc[Idempotent Consumer EIP guide].
-Sizing. An in-memory register smaller than the directory evicts keys and re-ingests those files during normal operation — hence the 100,000 default. `FileIdempotentRepository` falls back to its file store on a cache miss, so `cacheSize` is a performance setting; the correctness limit is `maxFileStoreSize`: the default of about 1 MB holds roughly 10–17 thousand of these keys, beyond it the oldest 1000 are dropped with a warning. A JDBC register has no size limit. Every edit adds a new key [...]
+Sizing.
+An in-memory register smaller than the directory evicts keys and re-ingests those files during normal operation — hence the 100,000 default.
+`FileIdempotentRepository` falls back to its file store on a cache miss, so `cacheSize` is a performance setting; the correctness limit is `maxFileStoreSize`: the default of about 1 MB holds roughly 10–17 thousand of these keys, beyond it the oldest 1000 are dropped with a warning.
+A JDBC register has no size limit.
+Every edit adds a new key and old keys are never removed, so a persistent register grows under churn until the synchronising engine arrives.
+There is no size option; size the bean.
+Use one register per pipeline — keys are source-derived, and pipelines sharing a register over the same directory skip each other's work.
-The register cannot be switched off: the consumer leaves files in place (`noop`), so without a register every poll would re-ingest the directory. To force a full re-ingest, restart (default register) or clear the persistent one. A pipeline that should consume its source — move or delete files after ingestion — uses `source.uri` (for example `file:/inbox?delete=true&idempotent=false` with `source.document-id=CamelFileName`), where all consumer options are available.
+The register cannot be switched off: the consumer leaves files in place (`noop`), so without a register every poll would re-ingest the directory.
+To force a full re-ingest, restart (default register) or clear the persistent one.
+A pipeline that should consume its source — move or delete files after ingestion — uses `source.uri` (for example `file:/inbox?delete=true&idempotent=false` with `source.document-id=CamelFileName`), where all consumer options are available.
-On a consumer-fed pipeline (`source.uri` or `@Ingest`), a configured register deduplicates deliveries by document id: a redelivered record or re-listed object ingests once, and a request-reply caller receives `skipped` instead of `ingested`. First write wins per id — an update with the same id is skipped, not replaced; streams that carry updates need a version-aware `source.document-id`. Only a delivery that wrote segments claims its id: a blank document answers `empty` and releases the [...]
+On a consumer-fed pipeline (`source.uri` or `@Ingest`), a configured register deduplicates deliveries by document id: a redelivered record or re-listed object ingests once, and a request-reply caller receives `skipped` instead of `ingested`.
+First write wins per id — an update with the same id is skipped, not replaced; streams that carry updates need a version-aware `source.document-id`.
+Only a delivery that wrote segments claims its id: a blank document answers `empty` and releases the claim, so an object created empty and populated later under the same id still ingests the content.
+With eager idempotency, a duplicate racing an in-flight first delivery is answered `skipped` even if that delivery then fails and releases the key.
+
+=== Parsing PDFs and office documents
+
+Setting `parser` puts a document parser between the consumer and the splitter:
+
+[source,properties]
+----
+quarkus.camel.langchain4j.ingest.reports.source.directory=/var/data/reports
+quarkus.camel.langchain4j.ingest.reports.parser=tika
+----
+
+`tika` extracts plain text in-process with Apache Tika.
+It needs the `camel-quarkus-tika` extension, plus the Tika parser module for each format the pipeline should read — `org.apache.tika:tika-parser-pdf-module` for PDF, say.
+A format without its module parses to nothing and the document is skipped as empty (logged as a warning); so is a scanned, image-only PDF, since Tika does no OCR here.
+On a directory pipeline an empty parse still commits the file's key in the duplicate register, so the file is not retried until it changes — after adding a missing parser module, force a re-ingest (restart with the default register, or clear the persistent one).
+A consumer-fed pipeline releases the claim of an empty delivery instead.
+
+`docling` converts documents to structure-preserving markdown through a https://github.com/docling-project/docling-serve[Docling Serve] instance, OCR included.
+It needs the `camel-quarkus-docling` extension and the instance's address in `camel.component.docling.docling-serve-url`.
+
+A missing parser extension fails the build naming the artifact, the same way a missing consumer component does.
+The Java twin is `IngestPipeline.parser("tika")`, and a consumer-fed pipeline parses the same way — the payload the consumer delivers goes to the parser first.
+With a parser, `max-document-size` also rejects a raw payload larger than the cap (in bytes) before it reaches the parser, on top of capping the extracted text (in characters).
=== Other sources, declared in Java
-Any Camel consumer can feed a pipeline — the roughly 300 components, each with its own options and its own documentation. Such a pipeline is declared in Java with `@Ingest` and the Camel Endpoint DSL:
+Any Camel consumer can feed a pipeline — the roughly 300 components, each with its own options and its own documentation.
+Such a pipeline is declared in Java with `@Ingest` and the Camel Endpoint DSL:
[source,java]
----
@@ -80,13 +130,20 @@ IngestPipeline events() {
}
----
-Typing `dsl.` lists a factory for every component, each completing its own typed options. The method runs once at startup; it must return `IngestPipeline`, take no parameters and use a name no configured pipeline uses. `enabled=false` in configuration switches a Java-declared pipeline off. A component missing from the classpath fails at startup with an error naming the extension artifact that provides it — the DSL compiles regardless, since its factories all ship in one artifact.
+Typing `dsl.` lists a factory for every component, each completing its own typed options.
+The method runs once at startup; it must return `IngestPipeline`, take no parameters and use a name no configured pipeline uses.
+`enabled=false` in configuration switches a Java-declared pipeline off.
+A component missing from the classpath fails at startup with an error naming the extension artifact that provides it — the DSL compiles regardless, since its factories all ship in one artifact.
-Ingestion needs a stable id per document, and where it lives is the consumer's business: `documentId` names the header — the record key `CamelKafkaKey` above, `CamelAwsS3Key` for S3 — or gives a simple-language expression. Without it, the pipeline expects the `CamelLangChain4jIngestDocumentId` header — the `camel-langchain4j-ingest` component's convention; the 3.39 name `CamelIngestDocumentId` is still read as a fallback, see the migration guide — and fails the exchange when both are abs [...]
+Ingestion needs a stable id per document, and where it lives is the consumer's business: `documentId` names the header — the record key `CamelKafkaKey` above, `CamelAwsS3Key` for S3 — or gives a simple-language expression.
+Without it, the pipeline expects the `CamelLangChain4jIngestDocumentId` header — the `camel-langchain4j-ingest` component's convention; the 3.39 name `CamelIngestDocumentId` is still read as a fallback, see the migration guide — and fails the exchange when both are absent.
+Mind each component's own defaults, too: the `aws2-s3` consumer *deletes objects after reading them* unless `deleteAfterRead(false)` is set — a knowledge base reads its source, it does not consume it.
After such a pipeline ingests a document, the exchange body is replaced with the `IngestResult`, so a request-reply caller receives the outcome of its call.
-The same pipeline can be declared purely in properties: `source.uri` takes the consumer URI as written, `source.document-id` the header name — or a simple-language expression written `+$simple{...}+`, the one form MicroProfile Config leaves untouched. The URI is fixed at build time by design — a runtime-overridable consumer URI would be arbitrary component invocation — while property placeholders inside it still resolve at startup, keeping credentials and endpoints runtime configuration. [...]
+The same pipeline can be declared purely in properties: `source.uri` takes the consumer URI as written, `source.document-id` the header name — or a simple-language expression written `+$simple{...}+`, the one form MicroProfile Config leaves untouched.
+The URI is fixed at build time by design — a runtime-overridable consumer URI would be arbitrary component invocation — while property placeholders inside it still resolve at startup, keeping credentials and endpoints runtime configuration.
+Treat runtime configuration as the trust boundary it is: the directory and the id expression decide what the process reads into an often external store.
[source,properties]
----
@@ -97,4 +154,7 @@ quarkus.camel.langchain4j.ingest.s3docs.embedding-store=products
=== When ingestion fails
-A failure while splitting, embedding or storing — a rate-limited model, an unreachable store — propagates to the consumer; there is no dead-letter channel in this increment. For a directory pipeline the file stays where it is and is retried on the next poll, because the duplicate-protection key is only committed on success — which also means a permanently failing file is retried forever, loudly. For a consumer-fed pipeline the component's own error handling applies: a request-reply calle [...]
+A failure while parsing, splitting, embedding or storing — an encrypted or corrupt document, an unreachable docling-serve, a rate-limited model, an unreachable store — propagates to the consumer; there is no dead-letter channel in this increment.
+For a directory pipeline the file stays where it is and is retried on the next poll, because the duplicate-protection key is only committed on success — which also means a permanently failing file is retried forever, loudly, on every poll: with a parser that includes a document the parser cannot read, so remove or fix such a file, or declare the pipeline with `source.uri` and the file consumer's `moveFailed` option to quarantine failures instead.
+For a consumer-fed pipeline the component's own error handling applies: a request-reply caller receives the exception, while a Kafka consumer with default settings logs the failure and commits the offset, so the record is *dropped* — and since this engine keeps no record either, nothing remembers it.
+A record whose configured `document-id` resolves to nothing (a Kafka record without a key, say) fails the same way, one exchange at a time.
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestBuildTimeConfig.java b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestBuildTimeConfig.java
index a11df04a85..98742f8d64 100644
--- a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestBuildTimeConfig.java
+++ b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestBuildTimeConfig.java
@@ -40,6 +40,12 @@ public interface IngestBuildTimeConfig {
/** Mirrors the {@code @WithDefault} below, which can only carry a literal. */
int DEFAULT_MAX_OVERLAP_SIZE = 50;
+ /** Mirrors the {@code @WithDefault} below, which can only carry a literal. */
+ int DEFAULT_EMBEDDING_BATCH_SIZE = 32;
+
+ /** Mirrors the {@code @WithDefault} below, which can only carry a literal; 0 means no limit. */
+ int DEFAULT_MAX_DOCUMENT_SIZE = 0;
+
/**
* Ingestion pipelines by name.
*/
@@ -54,6 +60,16 @@ public interface IngestBuildTimeConfig {
*/
SourceBuildTimeConfig source();
+ /**
+ * How a consumed payload becomes text before it is split: `tika` extracts plain text
+ * from PDF, office and similar formats in-process, `docling` converts to
+ * structure-preserving markdown through a Docling Serve instance (configure it with
+ * `camel.component.docling.*`). When not set, the payload is read as text as-is. Each
+ * value needs its extension on the classpath: `camel-quarkus-tika` or
+ * `camel-quarkus-docling`.
+ */
+ Optional<String> parser();
+
/**
* Name of the `EmbeddingStore` bean to write to. When not set, the only one present is
* used.
@@ -79,6 +95,32 @@ public interface IngestBuildTimeConfig {
@WithDefault("50")
int maxOverlapSize();
+ /**
+ * How many segments are embedded per request to the embedding model. Providers with
+ * generous per-request limits ingest large documents faster with a bigger batch; a batch
+ * carries at most `embedding-batch-size` × `max-segment-size` characters, so tune the two
+ * together against the provider's token limits.
+ */
+ @WithDefault("32")
+ int embeddingBatchSize();
+
+ /**
+ * Maximum size of one document in characters, applied to the text about to be split;
+ * 0, the default, means no limit. The pipeline holds a document in memory whole, so the
+ * cap is the protection against oversized — on a consumer-fed pipeline, attacker-sized —
+ * payloads. An oversized document fails the exchange cleanly.
+ */
+ @WithDefault("0")
+ int maxDocumentSize();
+
+ /**
+ * Name of the `DocumentSplitter` bean replacing the default recursive splitting;
+ * `max-segment-size` and `max-overlap-size` are then ignored. Looked up by name only —
+ * an application may hold unrelated splitters. Segments returned without the identity
+ * metadata are re-stamped, so a custom splitter cannot break citation.
+ */
+ Optional<String> documentSplitter();
+
/**
* A pipeline reads either a directory or a Camel consumer, and the two halves of that
* choice deliberately sit in different config roots: the consumer URI is fixed at build
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestComponentPresence.java b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestComponentPresence.java
index 7fb10e8ae9..ce6e1e5539 100644
--- a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestComponentPresence.java
+++ b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestComponentPresence.java
@@ -72,6 +72,17 @@ final class IngestComponentPresence {
if ("endpoint".equals(definition.sourceType())) {
require(context, entry.name(), definition.sourceUri());
}
+ // a builder-declared parser is out of reach of the build-time check, like the URI;
+ // resolved without starting the component - the route builder starts it later. No
+ // catch on purpose: a component that resolves but fails to initialise surfaces its
+ // real error, only an unresolvable one earns the artifact hint below
+ String parser = definition.parser().orElse(null);
+ if (parser != null && context.getComponent(parser, true, false) == null) {
+ throw new IllegalStateException("Ingestion pipeline '" + entry.name() + "' parses with '" + parser
+ + "', but the Camel component '" + parser + "' is not on the classpath. "
+ + "Add the extension that provides it, e.g. org.apache.camel.quarkus:camel-quarkus-"
+ + parser);
+ }
}
}
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipeline.java b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipeline.java
index 7f677daf48..d5c9ad8c9e 100644
--- a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipeline.java
+++ b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipeline.java
@@ -17,6 +17,7 @@
package org.apache.camel.quarkus.component.langchain4j.ingest;
import java.util.Optional;
+import java.util.Set;
/**
* A pipeline declared in Java rather than in configuration, returned from an {@link Ingest}
@@ -24,11 +25,18 @@ import java.util.Optional;
*/
public final class IngestPipeline {
+ /** The values {@link #parser(String)} and the {@code parser} configuration property accept. */
+ public static final Set<String> SUPPORTED_PARSERS = IngestPipelineDefinition.SUPPORTED_PARSERS;
+
private final Source source;
private String embeddingStoreName;
private String embeddingModelName;
+ private String parser;
private int maxSegmentSize = IngestBuildTimeConfig.DEFAULT_MAX_SEGMENT_SIZE;
private int maxOverlapSize = IngestBuildTimeConfig.DEFAULT_MAX_OVERLAP_SIZE;
+ private int embeddingBatchSize = IngestBuildTimeConfig.DEFAULT_EMBEDDING_BATCH_SIZE;
+ private int maxDocumentSize = IngestBuildTimeConfig.DEFAULT_MAX_DOCUMENT_SIZE;
+ private String documentSplitterName;
private IngestPipeline(Source source) {
this.source = source;
@@ -48,6 +56,23 @@ public final class IngestPipeline {
return this;
}
+ /**
+ * Parses the consumed payload into text before splitting: {@code tika} extracts plain text
+ * in-process, {@code docling} converts to markdown through a Docling Serve instance. The
+ * corresponding extension must be on the classpath; the twin of the {@code parser}
+ * configuration property.
+ */
+ public IngestPipeline parser(String parser) {
+ // the same rule the configuration path is held to at build time; the null check comes
+ // first because the unmodifiable set's contains(null) throws a bare NPE
+ if (parser == null || !SUPPORTED_PARSERS.contains(parser)) {
+ throw new IllegalArgumentException("parser must be one of " + SUPPORTED_PARSERS
+ + " (got '" + parser + "')");
+ }
+ this.parser = parser;
+ return this;
+ }
+
public IngestPipeline splitter(int maxSegmentSize, int maxOverlapSize) {
// the same rule the configuration path is held to at build time, so both paths reject
// the same values rather than failing later inside the splitter
@@ -60,6 +85,44 @@ public final class IngestPipeline {
return this;
}
+ /**
+ * How many segments are embedded per request to the embedding model; the twin of the
+ * {@code embedding-batch-size} configuration property.
+ */
+ public IngestPipeline embeddingBatchSize(int embeddingBatchSize) {
+ // the same rule the configuration path is held to at build time
+ if (embeddingBatchSize < 1) {
+ throw new IllegalArgumentException(
+ "embedding-batch-size must be positive (got " + embeddingBatchSize + ")");
+ }
+ this.embeddingBatchSize = embeddingBatchSize;
+ return this;
+ }
+
+ /**
+ * Maximum size of one document in characters; 0, the default, means no limit. The twin of
+ * the {@code max-document-size} configuration property.
+ */
+ public IngestPipeline maxDocumentSize(int maxDocumentSize) {
+ // the same rule the configuration path is held to at build time
+ if (maxDocumentSize < 0) {
+ throw new IllegalArgumentException(
+ "max-document-size must not be negative, 0 meaning no limit (got " + maxDocumentSize + ")");
+ }
+ this.maxDocumentSize = maxDocumentSize;
+ return this;
+ }
+
+ /**
+ * Name of the {@code DocumentSplitter} bean replacing the default recursive splitting; the
+ * twin of the {@code document-splitter} configuration property. The splitter sizes are then
+ * ignored.
+ */
+ public IngestPipeline documentSplitter(String beanName) {
+ this.documentSplitterName = beanName;
+ return this;
+ }
+
String sourceType() {
return source.type();
}
@@ -76,6 +139,10 @@ public final class IngestPipeline {
return Optional.ofNullable(embeddingModelName);
}
+ Optional<String> parser() {
+ return Optional.ofNullable(parser);
+ }
+
int maxSegmentSize() {
return maxSegmentSize;
}
@@ -84,6 +151,18 @@ public final class IngestPipeline {
return maxOverlapSize;
}
+ int embeddingBatchSize() {
+ return embeddingBatchSize;
+ }
+
+ int maxDocumentSize() {
+ return maxDocumentSize;
+ }
+
+ Optional<String> documentSplitterName() {
+ return Optional.ofNullable(documentSplitterName);
+ }
+
/** The configuration view, so a builder pipeline reuses every configuration path verbatim. */
IngestRunTimeConfig.PipelineRunTimeConfig asRunTimeConfig() {
IngestRunTimeConfig.PipelineRunTimeConfig.SourceRunTimeConfig sourceConfig = source.asRunTimeConfig();
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipelineDefinition.java b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipelineDefinition.java
new file mode 100644
index 0000000000..e94a65684e
--- /dev/null
+++ b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipelineDefinition.java
@@ -0,0 +1,351 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import dev.langchain4j.data.segment.TextSegment;
+import dev.langchain4j.model.embedding.EmbeddingModel;
+import dev.langchain4j.store.embedding.EmbeddingStore;
+import org.apache.camel.builder.EndpointConsumerBuilder;
+
+/**
+ * A declarative description of one ingestion pipeline, turned into a route by {@link IngestPipelineRouteBuilder}: what
+ * to consume, how to identify each document, whether to parse it, and where to embed and store it.
+ *
+ * <p>
+ * A pipeline reads either a directory ({@link #directory(String, String)}) or any Camel consumer
+ * ({@link #consumer(String, String)}); every other property has a matching endpoint option on the
+ * {@code langchain4j-ingest} producer the generated route ends in.
+ *
+ * <p>
+ * An internal copy of the pipeline assembly proposed alongside the upstream component — see
+ * {@link IngestPipelineRouteBuilder}.
+ */
+final class IngestPipelineDefinition {
+
+ /** The supported document parsers; the configuration value is the lower-case name. */
+ public enum Parser {
+ TIKA,
+ DOCLING;
+
+ static Parser of(String value) {
+ try {
+ return valueOf(value.toUpperCase(Locale.ROOT));
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(
+ "parser must be one of " + SUPPORTED_PARSERS + " (got '" + value + "')");
+ }
+ }
+ }
+
+ // derived from the enum, so a parser added there cannot diverge from the validated set
+ public static final Set<String> SUPPORTED_PARSERS = Arrays.stream(Parser.values())
+ .map(parser -> parser.name().toLowerCase(Locale.ROOT))
+ .collect(Collectors.toUnmodifiableSet());
+
+ private final String name;
+ private final String directory;
+ private final String uri;
+
+ private boolean recursive = true;
+ private String documentId;
+ private Parser parser;
+ private int maxSegmentSize = IngestBuildTimeConfig.DEFAULT_MAX_SEGMENT_SIZE;
+ private int maxOverlapSize = IngestBuildTimeConfig.DEFAULT_MAX_OVERLAP_SIZE;
+ private int embeddingBatchSize = IngestBuildTimeConfig.DEFAULT_EMBEDDING_BATCH_SIZE;
+ private int maxDocumentSize = IngestBuildTimeConfig.DEFAULT_MAX_DOCUMENT_SIZE;
+
+ private String embeddingStoreRef;
+ private EmbeddingStore<TextSegment> embeddingStore;
+ private String embeddingModelRef;
+ private EmbeddingModel embeddingModel;
+ private String documentSplitterRef;
+
+ private String idempotentRepositoryRef;
+ private boolean idempotentRepositoryAutoCreate;
+
+ private IngestPipelineDefinition(String name, String directory, String uri) {
+ this.name = name;
+ this.directory = directory;
+ this.uri = uri;
+ }
+
+ /**
+ * A pipeline reading the files of a directory: they are left in place (a knowledge base reads its source, it does
+ * not consume it), unchanged files are remembered and skipped, and a file still being copied in is waited for
+ * rather than half-ingested.
+ */
+ public static IngestPipelineDefinition directory(String name, String directory) {
+ requireText(directory, "directory");
+ if (directory.contains("?") || directory.contains("#")) {
+ throw new IllegalArgumentException(
+ "Ingestion pipeline '" + name + "': the directory must not contain '?' or '#' (got '"
+ + directory + "')");
+ }
+ return new IngestPipelineDefinition(requireName(name), directory, null);
+ }
+
+ /**
+ * A pipeline consuming from any Camel component, with the component's own options — the escape hatch beside
+ * {@link #directory(String, String)}. Which part of the exchange identifies the document is the consumer's
+ * business, so say it with {@link #documentId}: {@code CamelAwsS3Key} for an S3 consumer, {@code CamelKafkaKey} for
+ * a Kafka one.
+ */
+ public static IngestPipelineDefinition consumer(String name, String uri) {
+ requireText(uri, "uri");
+ if (!uri.contains(":")) {
+ throw new IllegalArgumentException(
+ "Ingestion pipeline '" + name + "': '" + uri + "' is not a consumer URI");
+ }
+ return new IngestPipelineDefinition(requireName(name), null, uri);
+ }
+
+ /**
+ * The same, built with the Camel Endpoint DSL (add the {@code camel-endpointdsl} dependency and use its static
+ * builders or an {@code EndpointBuilderFactory}).
+ */
+ public static IngestPipelineDefinition consumer(String name, EndpointConsumerBuilder uri) {
+ return consumer(name, uri.getRawUri());
+ }
+
+ /** Whether subdirectories are ingested too; directory pipelines only. */
+ public IngestPipelineDefinition recursive(boolean recursive) {
+ this.recursive = recursive;
+ return this;
+ }
+
+ /**
+ * Where the document id lives in the exchange the consumer delivers: the name of a header, or a simple-language
+ * expression (a value containing {@code ${} or {@code $simple{} is parsed as one). When not set, a directory
+ * pipeline uses the file name and a consumer pipeline the {@code CamelLangChain4jIngestDocumentId} header. The id
+ * is captured before any parse, so a document cannot forge its own identity.
+ */
+ public IngestPipelineDefinition documentId(String documentId) {
+ this.documentId = requireText(documentId, "documentId");
+ return this;
+ }
+
+ /**
+ * Parses the consumed payload into text before splitting: {@code tika} extracts plain text in-process,
+ * {@code docling} converts to markdown through a Docling Serve instance. The corresponding component must be on the
+ * classpath: {@code camel-tika} or {@code camel-docling}.
+ */
+ public IngestPipelineDefinition parser(String parser) {
+ this.parser = Parser.of(requireText(parser, "parser"));
+ return this;
+ }
+
+ /**
+ * The typed twin of {@link #parser(String)}, for Java callers; the String form exists for configuration
+ * translators, whose input is text by nature.
+ */
+ public IngestPipelineDefinition parser(Parser parser) {
+ if (parser == null) {
+ throw new IllegalArgumentException("Ingestion pipeline parser must not be null");
+ }
+ this.parser = parser;
+ return this;
+ }
+
+ /** The splitter bounds; the same rule the endpoint enforces, failing early here. */
+ public IngestPipelineDefinition splitter(int maxSegmentSize, int maxOverlapSize) {
+ if (maxSegmentSize <= 0 || maxOverlapSize < 0 || maxOverlapSize >= maxSegmentSize) {
+ throw new IllegalArgumentException(
+ "Ingestion pipeline '" + name + "': maxSegmentSize must be positive and maxOverlapSize must be"
+ + " non-negative and smaller than it (got " + maxSegmentSize + " / "
+ + maxOverlapSize + ")");
+ }
+ this.maxSegmentSize = maxSegmentSize;
+ this.maxOverlapSize = maxOverlapSize;
+ return this;
+ }
+
+ /**
+ * How many segments are embedded per request to the embedding model; the same rule the endpoint enforces, failing
+ * early here. A batch carries at most {@code embeddingBatchSize x maxSegmentSize} characters, so tune the two
+ * together against the provider's token limits.
+ */
+ public IngestPipelineDefinition embeddingBatchSize(int embeddingBatchSize) {
+ if (embeddingBatchSize < 1) {
+ throw new IllegalArgumentException(
+ "Ingestion pipeline '" + name + "': embeddingBatchSize must be positive (got "
+ + embeddingBatchSize + ")");
+ }
+ this.embeddingBatchSize = embeddingBatchSize;
+ return this;
+ }
+
+ /**
+ * Maximum size of one document; unset means no limit. The pipeline holds a document in memory whole, so the cap is
+ * the protection against oversized — on a consumer-fed pipeline, attacker-sized — payloads. It is enforced twice: a
+ * pipeline with a {@link #parser(Parser)} rejects a larger raw payload (in bytes) before the parse ever runs, and
+ * the endpoint rejects longer extracted text (in characters) before splitting — a small file can still parse into a
+ * lot of text. An oversized document fails the exchange cleanly: a directory pipeline quarantines it like any other
+ * failure, a consumer pipeline propagates the error to its source, and a dedup claim is released either way.
+ */
+ public IngestPipelineDefinition maxDocumentSize(int maxDocumentSize) {
+ if (maxDocumentSize < 0) {
+ throw new IllegalArgumentException(
+ "Ingestion pipeline '" + name + "': maxDocumentSize must not be negative, 0 meaning no limit (got "
+ + maxDocumentSize + ")");
+ }
+ this.maxDocumentSize = maxDocumentSize;
+ return this;
+ }
+
+ /**
+ * Name of the {@code DocumentSplitter} bean replacing the default recursive splitting; {@code maxSegmentSize} and
+ * {@code maxOverlapSize} are then ignored. Referenced by name on purpose — an application may hold unrelated
+ * splitters, so none is picked up by type. Segments returned without the identity metadata are re-stamped, so a
+ * custom splitter cannot break citation.
+ */
+ public IngestPipelineDefinition documentSplitter(String beanName) {
+ this.documentSplitterRef = requireText(beanName, "documentSplitter");
+ return this;
+ }
+
+ /** Name of the {@code EmbeddingStore} bean to write to; omitted, the single bean of the type is used. */
+ public IngestPipelineDefinition embeddingStore(String beanName) {
+ this.embeddingStoreRef = requireText(beanName, "embeddingStore");
+ return this;
+ }
+
+ /** The {@code EmbeddingStore} to write to, as an instance; it is bound to the registry under a generated name. */
+ public IngestPipelineDefinition embeddingStore(EmbeddingStore<TextSegment> store) {
+ this.embeddingStore = store;
+ return this;
+ }
+
+ /** Name of the {@code EmbeddingModel} bean to embed with; omitted, the single bean of the type is used. */
+ public IngestPipelineDefinition embeddingModel(String beanName) {
+ this.embeddingModelRef = requireText(beanName, "embeddingModel");
+ return this;
+ }
+
+ /** The {@code EmbeddingModel} to embed with, as an instance; it is bound to the registry under a generated name. */
+ public IngestPipelineDefinition embeddingModel(EmbeddingModel model) {
+ this.embeddingModel = model;
+ return this;
+ }
+
+ /**
+ * Name of the {@code IdempotentRepository} bean remembering ingested documents. A directory pipeline uses it in its
+ * file consumer, keyed on path, modification time and size, so a persistent repository makes restarts free. A
+ * consumer pipeline deduplicates deliveries by document id: first write wins.
+ */
+ public IngestPipelineDefinition idempotentRepository(String beanName) {
+ this.idempotentRepositoryRef = requireText(beanName, "idempotentRepository");
+ return this;
+ }
+
+ /**
+ * When {@code true}, an in-memory register (100 000 keys, lost on restart) is created and bound under the
+ * {@link #idempotentRepository(String)} name, unless a bean with that name exists — the existing bean wins.
+ */
+ public IngestPipelineDefinition idempotentRepositoryAutoCreate(boolean autoCreate) {
+ this.idempotentRepositoryAutoCreate = autoCreate;
+ return this;
+ }
+
+ private static String requireName(String name) {
+ requireText(name, "name");
+ if (!name.matches("[A-Za-z0-9._-]+")) {
+ throw new IllegalArgumentException(
+ "Ingestion pipeline name '" + name + "' may only contain letters, digits, '.', '_' and '-'");
+ }
+ return name;
+ }
+
+ private static String requireText(String value, String what) {
+ if (value == null || value.isBlank()) {
+ throw new IllegalArgumentException("Ingestion pipeline " + what + " must not be null or blank");
+ }
+ return value;
+ }
+
+ String name() {
+ return name;
+ }
+
+ String directory() {
+ return directory;
+ }
+
+ String uri() {
+ return uri;
+ }
+
+ boolean recursive() {
+ return recursive;
+ }
+
+ String documentId() {
+ return documentId;
+ }
+
+ Parser parser() {
+ return parser;
+ }
+
+ int maxSegmentSize() {
+ return maxSegmentSize;
+ }
+
+ int maxOverlapSize() {
+ return maxOverlapSize;
+ }
+
+ int embeddingBatchSize() {
+ return embeddingBatchSize;
+ }
+
+ int maxDocumentSize() {
+ return maxDocumentSize;
+ }
+
+ String documentSplitterRef() {
+ return documentSplitterRef;
+ }
+
+ String embeddingStoreRef() {
+ return embeddingStoreRef;
+ }
+
+ EmbeddingStore<TextSegment> embeddingStore() {
+ return embeddingStore;
+ }
+
+ String embeddingModelRef() {
+ return embeddingModelRef;
+ }
+
+ EmbeddingModel embeddingModel() {
+ return embeddingModel;
+ }
+
+ String idempotentRepositoryRef() {
+ return idempotentRepositoryRef;
+ }
+
+ boolean idempotentRepositoryAutoCreate() {
+ return idempotentRepositoryAutoCreate;
+ }
+}
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipelineRouteBuilder.java b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipelineRouteBuilder.java
new file mode 100644
index 0000000000..d945eeee5e
--- /dev/null
+++ b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestPipelineRouteBuilder.java
@@ -0,0 +1,458 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.camel.Component;
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.langchain4j.ingest.IngestResult;
+import org.apache.camel.component.langchain4j.ingest.LangChain4jIngest;
+import org.apache.camel.component.langchain4j.ingest.LangChain4jIngestHeaders;
+import org.apache.camel.component.langchain4j.ingest.TikaTextDecode;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.spi.IdempotentRepository;
+import org.apache.camel.support.ExpressionAdapter;
+import org.apache.camel.support.builder.ExpressionBuilder;
+import org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.URISupport;
+
+/**
+ * Generates one Camel route per {@link IngestPipelineDefinition}: consume, resolve the document id, optionally parse,
+ * then split, embed and store through the {@code langchain4j-ingest} producer.
+ *
+ * <p>
+ * A directory pipeline watches its folder with the safe file-consumer defaults — documents are left in place, unchanged
+ * files are remembered in a duplicate register keyed on path, modification time and size, and a file still being copied
+ * in is waited for. A consumer pipeline reads any component and deduplicates by document id when a repository is
+ * configured. The id is always captured into an exchange property <em>before</em> the parse stage: a parser copies
+ * document metadata over the headers, so a crafted document could otherwise forge its own identity.
+ *
+ * <p>
+ * An internal copy of the pipeline assembly proposed alongside the upstream component: the delegation to Apache Camel
+ * is engine-only, so the topology lives here, package-private — replaceable by an upstream artifact or kamelets if the
+ * community adopts one of them.
+ *
+ * <p>
+ * The class is abstract on purpose: camel-quarkus routes discovery instantiates every concrete public
+ * {@code RouteBuilder} it finds reflectively, and an abstract base is skipped by construction.
+ */
+abstract class IngestPipelineRouteBuilder extends RouteBuilder {
+
+ /**
+ * The built-in register capacity, sized above Camel's 1000-entry default so eviction does not re-ingest large
+ * directories during normal operation; in-memory, so lost on restart.
+ */
+ static final int DEFAULT_REGISTER_CAPACITY = 100_000;
+
+ /**
+ * The pipelines to build routes for; supplied by the subclass assembling its definitions from another source — a
+ * configuration model, say.
+ */
+ protected abstract List<IngestPipelineDefinition> pipelines();
+
+ @Override
+ public void configure() {
+ Set<String> names = new HashSet<>();
+ for (IngestPipelineDefinition pipeline : pipelines()) {
+ if (!names.add(pipeline.name())) {
+ throw new IllegalArgumentException(
+ "Ingestion pipeline '" + pipeline.name() + "' is defined twice. Use one name per pipeline.");
+ }
+ configurePipeline(pipeline);
+ }
+ }
+
+ private void configurePipeline(IngestPipelineDefinition pipeline) {
+ requireParserComponent(pipeline);
+ String storeRef = bindInstance(pipeline.embeddingStore(), pipeline.embeddingStoreRef(), pipeline, "store");
+ String modelRef = bindInstance(pipeline.embeddingModel(), pipeline.embeddingModelRef(), pipeline, "model");
+ String splitterRef = pipeline.documentSplitterRef();
+
+ if (pipeline.directory() != null) {
+ directoryRoute(pipeline, storeRef, modelRef, splitterRef);
+ log.info("Ingestion pipeline '{}': source=file:{}", pipeline.name(), pipeline.directory());
+ } else {
+ consumerRoute(pipeline, storeRef, modelRef, splitterRef);
+ log.info("Ingestion pipeline '{}': source={}", pipeline.name(), URISupport.sanitizeUri(pipeline.uri()));
+ }
+ }
+
+ // ********************************************************************************
+ // The two route topologies
+ // ********************************************************************************
+
+ /**
+ * The route: watch the directory → resolve the id → (parse) → split, embed, store. The register in the file
+ * endpoint keeps unchanged files from re-ingesting; an edited file gets a new key and re-ingests, its old segments
+ * remain.
+ */
+ private void directoryRoute(IngestPipelineDefinition pipeline, String storeRef, String modelRef, String splitterRef) {
+ String registerRef = repositoryRef(pipeline, true);
+ Expression documentId = documentIdExpression(pipeline.name(), pipeline.documentId(), Exchange.FILE_NAME);
+
+ ProcessorDefinition<?> route = from(fileEndpointUri(pipeline, registerRef))
+ .routeId(routeId(pipeline))
+ .setProperty(LangChain4jIngest.DOCUMENT_ID_PROPERTY, documentId);
+ // no duplicate pre-check: the endpoint register already filtered duplicates out
+ route = parseSteps(route, pipeline, null);
+ // the file consumer discards the reply, so no repository is passed to the producer: the
+ // endpoint register already keeps the same file version from being ingested twice
+ ProcessorDefinition<?> tail = route.to(ingestEndpointUri(pipeline, storeRef, modelRef, splitterRef, null, null));
+ if (pipeline.parser() != null) {
+ // the discarded reply would otherwise hide it: a parse to nothing typically means a
+ // missing Tika parser module or an image-only document, and the file's register key
+ // is committed, so it is not retried until the file changes
+ tail.process(exchange -> {
+ IngestResult result = exchange.getMessage().getBody(IngestResult.class);
+ if (result != null && result.outcome() == IngestResult.Outcome.EMPTY) {
+ log.warn("Ingestion pipeline '{}': document '{}' parsed to no text and was skipped; its key is"
+ + " committed, so it is not retried until the file changes (missing parser module?"
+ + " image-only document?)",
+ pipeline.name(), result.documentId());
+ }
+ });
+ } else {
+ // the discarded reply would otherwise hide even the trace of a blank file
+ tail.process(exchange -> {
+ IngestResult result = exchange.getMessage().getBody(IngestResult.class);
+ if (result != null && result.outcome() == IngestResult.Outcome.EMPTY) {
+ log.debug("Ingestion pipeline '{}': document '{}' contained no text, nothing was written",
+ pipeline.name(), result.documentId());
+ }
+ });
+ }
+ }
+
+ /** The route: consume → resolve the id → (parse) → split, embed, store; the reply is the result. */
+ private void consumerRoute(IngestPipelineDefinition pipeline, String storeRef, String modelRef, String splitterRef) {
+ String scheme = StringHelper.before(pipeline.uri(), ":");
+ requireComponent(scheme, pipeline, "its source");
+ String registerRef = repositoryRef(pipeline, false);
+ Expression documentId = documentIdExpression(pipeline.name(), pipeline.documentId(),
+ LangChain4jIngestHeaders.DOCUMENT_ID);
+ IdempotentRepository register = registerRef == null
+ ? null
+ : getContext().getRegistry().lookupByNameAndType(registerRef, IdempotentRepository.class);
+
+ ProcessorDefinition<?> route = from(pipeline.uri())
+ .routeId(routeId(pipeline))
+ .setProperty(LangChain4jIngest.DOCUMENT_ID_PROPERTY, documentId);
+ route = parseSteps(route, pipeline, register);
+ // deduplication by document id happens inside the producer, so a duplicate is answered
+ // SKIPPED, a blank delivery releases its claim and a failed write can be retried
+ // when the id comes from a plain header, the producer is told its name: the property set
+ // above always wins, but the producer's missing-id error then names the header the route
+ // actually reads instead of the component default
+ String configured = pipeline.documentId();
+ String documentIdHeader = configured != null && !configured.contains("${") && !configured.contains("$simple{")
+ ? configured
+ : null;
+ route.to(ingestEndpointUri(pipeline, storeRef, modelRef, splitterRef, registerRef, documentIdHeader));
+ }
+
+ /**
+ * The optional parse stage; the route is returned unchanged when the pipeline has no parser. Tika parses in-process
+ * to its plain-text output — body subtree only, block boundaries newline-separated by Tika's own handlers, the
+ * encoding pinned — and {@link TikaTextDecode} then decodes those bytes as the pinned charset, dodging the exchange
+ * charset heuristic that the parsed document's own Content-Type header could steer. Docling hands the payload to a
+ * Docling Serve instance and answers finished markdown; the body is pinned to bytes and the {@code CamelDocling*}
+ * control headers are swept, because none of them may be decided by a consumer-delivered payload.
+ */
+ private ProcessorDefinition<?> parseSteps(ProcessorDefinition<?> route, IngestPipelineDefinition pipeline,
+ IdempotentRepository register) {
+ if (pipeline.parser() == null) {
+ return route;
+ }
+ // a parser must never run without a captured id: the property would be unset, and the
+ // producer's header fallback would read headers a parsed document may have written -
+ // the previous engine failed such a delivery, and so does this guard
+ route = route.process(exchange -> {
+ String id = exchange.getProperty(LangChain4jIngest.DOCUMENT_ID_PROPERTY, String.class);
+ if (id == null || id.isBlank()) {
+ throw new IllegalArgumentException("Ingestion pipeline '" + pipeline.name()
+ + "': the document id resolved to nothing, and a parser pipeline requires it before"
+ + " the parse - a parsed document must not supply its own identity");
+ }
+ });
+ if (register != null) {
+ // advisory: a known duplicate is answered SKIPPED before the (possibly remote) parse
+ // is paid for; the producer's eager claim stays authoritative, so a duplicate racing
+ // this check is still caught there
+ route = route.choice()
+ .when(exchange -> register
+ .contains(exchange.getProperty(LangChain4jIngest.DOCUMENT_ID_PROPERTY, String.class)))
+ .process(exchange -> exchange.getMessage().setBody(new IngestResult(pipeline.name(),
+ exchange.getProperty(LangChain4jIngest.DOCUMENT_ID_PROPERTY, String.class), 0,
+ IngestResult.Outcome.SKIPPED)))
+ .stop()
+ .end();
+ }
+ if (pipeline.maxDocumentSize() > 0) {
+ // the endpoint's own cap counts extracted characters, which protects the splitter and
+ // the model but not the parse: this guard rejects the raw payload first, before tika
+ // or docling materialize it
+ route = route.process(rawSizeGuard(pipeline));
+ }
+ return switch (pipeline.parser()) {
+ case TIKA -> route.to("tika:parse?tikaParseOutputFormat=text&tikaParseOutputEncoding=UTF-8")
+ .process(new TikaTextDecode());
+ case DOCLING -> route.convertBodyTo(byte[].class)
+ .removeHeaders("CamelDocling*")
+ .to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
+ };
+ }
+
+ private static Processor rawSizeGuard(IngestPipelineDefinition pipeline) {
+ // the declared-length header spares even the read, but only the directory pipeline's own
+ // file consumer is trusted to have set it: on a consumer pipeline every header may be
+ // attacker-supplied along with the payload, so its body is always measured - a forged
+ // CamelFileLength must not talk an oversized payload past the guard and into the parser
+ boolean trustDeclaredLength = pipeline.directory() != null;
+ return exchange -> {
+ Long declared = trustDeclaredLength
+ ? exchange.getMessage().getHeader(Exchange.FILE_LENGTH, Long.class)
+ : null;
+ long size;
+ byte[] bounded = null;
+ if (declared != null) {
+ size = declared;
+ } else {
+ // every body is measured through a stream - a GenericFile streams from disk, a
+ // byte[] merely wraps - so an attacker-sized payload is rejected after
+ // maxDocumentSize + 1 bytes instead of being materialized whole in the heap just
+ // to be measured; an accepted stream is consumed here, so the bytes replace it
+ // as the body. A null body carries no bytes to guard; it flows on and becomes
+ // the EMPTY outcome
+ InputStream stream = exchange.getMessage().getBody(InputStream.class);
+ if (stream == null) {
+ size = 0;
+ } else {
+ int limit = pipeline.maxDocumentSize() == Integer.MAX_VALUE
+ ? Integer.MAX_VALUE
+ : pipeline.maxDocumentSize() + 1;
+ bounded = stream.readNBytes(limit);
+ size = bounded.length;
+ }
+ }
+ if (size > pipeline.maxDocumentSize()) {
+ throw new IllegalArgumentException(
+ "Ingestion pipeline '" + pipeline.name() + "': document '"
+ + exchange.getProperty(LangChain4jIngest.DOCUMENT_ID_PROPERTY,
+ String.class)
+ + "' exceeds maxDocumentSize (" + size + " > "
+ + pipeline.maxDocumentSize() + " bytes)");
+ }
+ if (bounded != null) {
+ exchange.getMessage().setBody(bounded);
+ }
+ };
+ }
+
+ // ********************************************************************************
+ // Helper methods
+ // ********************************************************************************
+
+ /**
+ * The directory consumer. Built through {@code createQueryString} rather than concatenated, so no option can be
+ * injected through a crafted value. {@code noop} leaves the documents where they are, the register keeps the same
+ * file version from being ingested twice, and the {@code changed} read lock waits for a file still being copied in.
+ */
+ private static String fileEndpointUri(IngestPipelineDefinition pipeline, String registerRef) {
+ Map<String, Object> options = new LinkedHashMap<>();
+ options.put("noop", "true");
+ options.put("idempotent", "true");
+ options.put("idempotentRepository", "#bean:" + registerRef);
+ // an edited file gets a new key and re-ingests; old segments remain (append)
+ options.put("idempotentKey", "${file:absolute.path}:${file:modified}:${file:size}");
+ options.put("recursive", String.valueOf(pipeline.recursive()));
+ options.put("readLock", "changed");
+ if (pipeline.parser() == null) {
+ // text is read as UTF-8; a parser receives the raw bytes instead - the format is its
+ // business, and a charset conversion would corrupt a binary document
+ options.put("charset", "UTF-8");
+ }
+ return "file:" + pipeline.directory() + "?" + queryString(options);
+ }
+
+ private static String ingestEndpointUri(
+ IngestPipelineDefinition pipeline, String storeRef, String modelRef, String splitterRef, String registerRef,
+ String documentIdHeader) {
+ Map<String, Object> options = new LinkedHashMap<>();
+ if (documentIdHeader != null) {
+ options.put("documentIdHeader", documentIdHeader);
+ }
+ options.put("maxSegmentSize", String.valueOf(pipeline.maxSegmentSize()));
+ options.put("maxOverlapSize", String.valueOf(pipeline.maxOverlapSize()));
+ options.put("embeddingBatchSize", String.valueOf(pipeline.embeddingBatchSize()));
+ if (pipeline.maxDocumentSize() > 0) {
+ options.put("maxDocumentSize", String.valueOf(pipeline.maxDocumentSize()));
+ }
+ if (splitterRef != null) {
+ options.put("documentSplitter", "#bean:" + splitterRef);
+ }
+ if (storeRef != null) {
+ options.put("embeddingStore", "#bean:" + storeRef);
+ }
+ if (modelRef != null) {
+ options.put("embeddingModel", "#bean:" + modelRef);
+ }
+ if (registerRef != null) {
+ options.put("idempotentRepository", "#bean:" + registerRef);
+ }
+ return LangChain4jIngest.SCHEME + ":" + pipeline.name() + "?" + queryString(options);
+ }
+
+ private static String queryString(Map<String, Object> options) {
+ return URISupport.createQueryString(options);
+ }
+
+ /**
+ * A bare header name is read as a header directly rather than parsed: a dotted header name would send the simple
+ * parser into OGNL. A value containing {@code ${} or {@code $simple{} is a simple-language expression. The
+ * expression is initialised here, at route build time — left to reify lazily it would race on the first concurrent
+ * exchanges.
+ */
+ /**
+ * When the id lives in the default {@code CamelLangChain4jIngestDocumentId} header, the 3.39
+ * name is still read as a fallback — each name keeping Camel's header-then-exchange-property
+ * lookup — and the deprecation is warned once per pipeline.
+ */
+ @SuppressWarnings("deprecation")
+ private Expression documentIdExpression(String name, String configured, String defaultHeader) {
+ if (configured != null && (configured.contains("${") || configured.contains("$simple{"))) {
+ Expression expression = ExpressionBuilder.simpleExpression(configured);
+ expression.init(getContext());
+ return expression;
+ }
+ String header = configured != null ? configured : defaultHeader;
+ if (!IngestHeaders.DOCUMENT_ID.equals(header)) {
+ Expression expression = ExpressionBuilder.headerExpression(header);
+ expression.init(getContext());
+ return expression;
+ }
+ Expression current = ExpressionBuilder.headerExpression(IngestHeaders.DOCUMENT_ID);
+ Expression legacy = ExpressionBuilder.headerExpression(IngestHeaders.LEGACY_DOCUMENT_ID);
+ current.init(getContext());
+ legacy.init(getContext());
+ return new ExpressionAdapter() {
+ private final AtomicBoolean warned = new AtomicBoolean();
+
+ @Override
+ public Object evaluate(Exchange exchange) {
+ Object id = current.evaluate(exchange, Object.class);
+ if (id != null) {
+ return id;
+ }
+ id = legacy.evaluate(exchange, Object.class);
+ if (id != null && warned.compareAndSet(false, true)) {
+ log.warn("Ingestion pipeline '{}': document id read via the deprecated {} name"
+ + " - switch the producer to {}",
+ name, IngestHeaders.LEGACY_DOCUMENT_ID, IngestHeaders.DOCUMENT_ID);
+ }
+ return id;
+ }
+ };
+ }
+
+ /**
+ * Resolves the pipeline's duplicate register to a registry reference: a named bean, an auto-created in-memory
+ * register — the existing bean wins — or, when a directory pipeline names none, the built-in one.
+ */
+ private String repositoryRef(IngestPipelineDefinition pipeline, boolean required) {
+ String ref = pipeline.idempotentRepositoryRef();
+ if (pipeline.idempotentRepositoryAutoCreate()) {
+ if (ref == null) {
+ throw new IllegalStateException(
+ "Ingestion pipeline '" + pipeline.name() + "' sets idempotentRepositoryAutoCreate but no"
+ + " idempotentRepository name to create the register under.");
+ }
+ if (getContext().getRegistry().lookupByNameAndType(ref, IdempotentRepository.class) == null) {
+ getContext().getRegistry().bind(ref,
+ MemoryIdempotentRepository.memoryIdempotentRepository(DEFAULT_REGISTER_CAPACITY));
+ }
+ }
+ if (ref == null && required) {
+ ref = generatedName(pipeline, "register");
+ if (getContext().getRegistry().lookupByNameAndType(ref, IdempotentRepository.class) == null) {
+ getContext().getRegistry().bind(ref,
+ MemoryIdempotentRepository.memoryIdempotentRepository(DEFAULT_REGISTER_CAPACITY));
+ }
+ }
+ return ref;
+ }
+
+ /**
+ * Binds a definition-supplied instance to the registry, so the endpoint can reference it;
+ * called from {@code configure()}, which Camel runs single-threaded during startup.
+ */
+ private String bindInstance(Object instance, String ref, IngestPipelineDefinition pipeline, String what) {
+ if (instance == null) {
+ return ref;
+ }
+ String name = ref != null ? ref : generatedName(pipeline, what);
+ getContext().getRegistry().bind(name, instance);
+ return name;
+ }
+
+ private void requireParserComponent(IngestPipelineDefinition pipeline) {
+ if (pipeline.parser() == null) {
+ return;
+ }
+ switch (pipeline.parser()) {
+ case TIKA -> requireComponent("tika", pipeline, "its parser");
+ case DOCLING -> requireComponent("docling", pipeline, "its parser");
+ }
+ }
+
+ /**
+ * Fails a pipeline whose component is not on the classpath with the artifact to add, instead of Camel's bare
+ * failed-to-resolve message much later.
+ */
+ private void requireComponent(String scheme, IngestPipelineDefinition pipeline, String purpose) {
+ Component component = null;
+ try {
+ component = getContext().getComponent(scheme, true, false);
+ } catch (Exception e) {
+ // fall through to the actionable message
+ }
+ if (component == null) {
+ throw new IllegalStateException(
+ "Ingestion pipeline '" + pipeline.name() + "' needs the '" + scheme + "' component for " + purpose
+ + ", which is not on the classpath. Add the extension that provides it, e.g. "
+ + "org.apache.camel.quarkus:camel-quarkus-" + scheme);
+ }
+ }
+
+ private static String generatedName(IngestPipelineDefinition pipeline, String what) {
+ return LangChain4jIngest.SCHEME + "-" + pipeline.name() + "-" + what;
+ }
+
+ private static String routeId(IngestPipelineDefinition pipeline) {
+ return LangChain4jIngest.SCHEME + "-" + pipeline.name();
+ }
+}
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestRoutes.java b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestRoutes.java
index 9155f9db91..88468bf595 100644
--- a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestRoutes.java
+++ b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/IngestRoutes.java
@@ -16,11 +16,10 @@
*/
package org.apache.camel.quarkus.component.langchain4j.ingest;
-import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
@@ -33,26 +32,18 @@ import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.literal.NamedLiteral;
import jakarta.inject.Inject;
import org.apache.camel.CamelContextAware;
-import org.apache.camel.Exchange;
-import org.apache.camel.Expression;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.quarkus.component.langchain4j.ingest.core.IngestResult;
-import org.apache.camel.quarkus.component.langchain4j.ingest.core.IngestService;
import org.apache.camel.spi.IdempotentRepository;
-import org.apache.camel.support.ExpressionAdapter;
-import org.apache.camel.support.builder.ExpressionBuilder;
-import org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository;
-import org.apache.camel.util.URISupport;
import org.jboss.logging.Logger;
-import static org.apache.camel.builder.endpoint.StaticEndpointBuilders.file;
-
/**
- * Generates one Camel route per configured ingestion pipeline. Users never see these routes —
- * they are the implementation of the configuration.
+ * Translates the extension's configuration model — build-time and runtime properties and
+ * {@code @Ingest} builder methods — into upstream {@link IngestPipelineDefinition}s; the routes
+ * themselves are generated by the inherited {@link IngestPipelineRouteBuilder}, and the engine
+ * lives in the {@code camel-langchain4j-ingest} component. What stays here is the Quarkus DX:
+ * CDI bean resolution with its actionable messages, and the configuration-level validations.
*/
@ApplicationScoped
-public class IngestRoutes extends RouteBuilder {
+public class IngestRoutes extends IngestPipelineRouteBuilder {
private static final Logger LOG = Logger.getLogger(IngestRoutes.class);
@@ -75,11 +66,10 @@ public class IngestRoutes extends RouteBuilder {
@Any
Instance<EmbeddingModel> modelCandidates;
- /** Exchange property carrying the resolved document id. */
- private static final String DOCUMENT_ID_PROPERTY = "CamelQuarkusIngestDocumentId";
-
@Override
- public void configure() {
+ protected List<IngestPipelineDefinition> pipelines() {
+ List<IngestPipelineDefinition> definitions = new ArrayList<>();
+
// a pipeline may be declared entirely through runtime properties - the documented
// minimum is a directory and nothing else - so the two config roots are unioned. Keying
// off the build-time map alone would make that configuration a silent no-op, since
@@ -100,13 +90,6 @@ public class IngestRoutes extends RouteBuilder {
continue;
}
- IngestService service = new IngestService(
- name,
- resolveStore(name, pipeline == null ? null : pipeline.embeddingStore().orElse(null)),
- resolveModel(name, pipeline == null ? null : pipeline.embeddingModel().orElse(null)),
- pipeline == null ? IngestBuildTimeConfig.DEFAULT_MAX_SEGMENT_SIZE : pipeline.maxSegmentSize(),
- pipeline == null ? IngestBuildTimeConfig.DEFAULT_MAX_OVERLAP_SIZE : pipeline.maxOverlapSize());
-
// a consumer URI says "consume from this"; its absence says "read that directory"
String uri = pipeline == null ? null : pipeline.source().uri().orElse(null);
if (uri != null && runtime != null && runtime.source().directory().isPresent()) {
@@ -114,29 +97,36 @@ public class IngestRoutes extends RouteBuilder {
+ "') and source.directory ('" + runtime.source().directory().get() + "'). A pipeline "
+ "reads one source: keep the URI, or drop it to read the directory.");
}
- if (uri == null) {
- configureFileSource(name, runtime, service);
- LOG.infof("Ingestion pipeline '%s': source=file", name);
- } else {
- configureEndpointSource(name, uri, runtime, service);
- LOG.infof("Ingestion pipeline '%s': source=%s", name, URISupport.sanitizeUri(uri));
- }
+
+ definitions.add(definition(name, uri, runtime,
+ resolveStore(name, pipeline == null ? null : pipeline.embeddingStore().orElse(null)),
+ resolveModel(name, pipeline == null ? null : pipeline.embeddingModel().orElse(null)),
+ pipeline == null ? IngestBuildTimeConfig.DEFAULT_MAX_SEGMENT_SIZE : pipeline.maxSegmentSize(),
+ pipeline == null ? IngestBuildTimeConfig.DEFAULT_MAX_OVERLAP_SIZE : pipeline.maxOverlapSize(),
+ pipeline == null ? IngestBuildTimeConfig.DEFAULT_EMBEDDING_BATCH_SIZE : pipeline.embeddingBatchSize(),
+ pipeline == null ? IngestBuildTimeConfig.DEFAULT_MAX_DOCUMENT_SIZE : pipeline.maxDocumentSize(),
+ pipeline == null ? null : pipeline.documentSplitter().orElse(null),
+ pipeline == null ? null : pipeline.parser().orElse(null)));
}
for (IngestBuilderPipelines.Entry entry : builderPipelines.entries()) {
- configureBuilderPipeline(entry);
+ IngestPipelineDefinition definition = builderPipeline(entry);
+ if (definition != null) {
+ definitions.add(definition);
+ }
}
+ return definitions;
}
/** An {@code @Ingest}-declared pipeline: the builder twin of the configuration path. */
- private void configureBuilderPipeline(IngestBuilderPipelines.Entry entry) {
+ private IngestPipelineDefinition builderPipeline(IngestBuilderPipelines.Entry entry) {
String name = entry.name();
// configuration can still switch a builder-declared pipeline off, and the check precedes
// the invocation so a disabled pipeline's method never runs
IngestRunTimeConfig.PipelineRunTimeConfig external = runTimeConfig.pipelines().get(name);
if (external != null && !external.enabled()) {
LOG.infof("Ingestion pipeline '%s' (builder) is disabled", name);
- return;
+ return null;
}
// enabled is the one thing configuration may say about a builder pipeline; anything about
// its source would be quietly overruled by the @Ingest method, so it is an error instead
@@ -152,178 +142,85 @@ public class IngestRoutes extends RouteBuilder {
}
IngestPipeline definition = builderPipelines.definition(entry);
- IngestRunTimeConfig.PipelineRunTimeConfig runtime = definition.asRunTimeConfig();
-
- IngestService service = new IngestService(
- name,
+ String uri = "file".equals(definition.sourceType()) ? null : definition.sourceUri();
+ return definition(name, uri, definition.asRunTimeConfig(),
resolveStore(name, definition.embeddingStoreName().orElse(null)),
resolveModel(name, definition.embeddingModelName().orElse(null)),
definition.maxSegmentSize(),
- definition.maxOverlapSize());
-
- switch (definition.sourceType()) {
- case "file" -> configureFileSource(name, runtime, service);
- case "endpoint" -> configureEndpointSource(name, definition.sourceUri(), runtime, service);
- default -> throw new IllegalStateException("Unknown source type " + definition.sourceType());
- }
-
- LOG.infof("Ingestion pipeline '%s' (builder): source=%s", name,
- URISupport.sanitizeUri(definition.sourceUri() == null ? definition.sourceType() : definition.sourceUri()));
- }
-
- private void configureFileSource(String name, IngestRunTimeConfig.PipelineRunTimeConfig runtime,
- IngestService service) {
- String directory = required(name, runtime == null ? null : runtime.source().directory().orElse(null),
- "source.directory");
- // built with the Endpoint DSL rather than concatenated: a directory containing ? # & or a
- // space would otherwise mis-parse, and a crafted one could inject options - delete=true
- // is honoured ahead of noop and would delete the user's documents after reading them.
- // noop leaves the documents where they are (a knowledge base reads its source, it does
- // not consume it), idempotent keeps the same file from being ingested twice, and the
- // changed read lock waits for a file still being copied in rather than embedding half
- // of it
- Expression documentId = documentIdExpression(name, runtime, Exchange.FILE_NAME);
- maybeAutoCreateRepository(name, runtime);
- String repositoryName = runtime == null ? null : runtime.source().idempotentRepository().orElse(null);
- var endpoint = file(directory)
- .noop(true)
- .idempotent(true);
- if (repositoryName != null) {
- endpoint.idempotentRepository(resolveRepository(name, repositoryName));
- } else {
- // in-memory default, sized above Camel's 1000-entry cap so eviction does not
- // re-ingest large directories; lost on restart
- endpoint.idempotentRepository(MemoryIdempotentRepository.memoryIdempotentRepository(100_000));
- }
- from(endpoint
- // an edited file gets a new key and re-ingests; old segments remain (append)
- .idempotentKey("${file:absolute.path}:${file:modified}:${file:size}")
- .recursive(runtime.source().recursive())
- .readLock("changed")
- .charset(StandardCharsets.UTF_8.name()))
- .routeId(routeId(name))
- .process(exchange -> {
- IngestResult result = service.ingest(documentId.evaluate(exchange, String.class),
- exchange.getIn().getBody(String.class));
- // the file consumer discards the result, so an EMPTY outcome would
- // otherwise leave no trace at all
- if (result.outcome() == IngestResult.Outcome.EMPTY) {
- LOG.debugf("Ingestion pipeline '%s': document '%s' contained no text, nothing was written",
- name, result.documentId());
- }
- });
+ definition.maxOverlapSize(),
+ definition.embeddingBatchSize(),
+ definition.maxDocumentSize(),
+ definition.documentSplitterName().orElse(null),
+ definition.parser().orElse(null));
}
/**
- * The escape hatch: any Camel consumer feeds the pipeline. Which part of the exchange
- * identifies the document is the consumer's business, so {@code source.document-id} says it —
- * {@code ${header.CamelAwsS3Key}} for an S3 consumer, the message header otherwise.
+ * One creation path for both declaration styles, mirroring how a builder pipeline provides
+ * the same runtime-configuration view the configuration path reads.
*/
- private void configureEndpointSource(String name, String uri,
- IngestRunTimeConfig.PipelineRunTimeConfig runtime, IngestService service) {
- Expression documentId = documentIdExpression(name, runtime, IngestHeaders.DOCUMENT_ID);
- maybeAutoCreateRepository(name, runtime);
- String repositoryName = runtime == null ? null : runtime.source().idempotentRepository().orElse(null);
- if (repositoryName == null) {
- from(uri)
- .routeId(routeId(name))
- .process(exchange -> {
- String id = requireDocumentId(name, documentId, exchange);
- exchange.getIn().setBody(service.ingest(id, exchange.getIn().getBody(String.class)));
- });
- return;
+ private IngestPipelineDefinition definition(String name, String uri,
+ IngestRunTimeConfig.PipelineRunTimeConfig runtime,
+ EmbeddingStore<TextSegment> store, EmbeddingModel model,
+ int maxSegmentSize, int maxOverlapSize, int embeddingBatchSize, int maxDocumentSize,
+ String documentSplitterName, String parser) {
+
+ IngestPipelineDefinition definition;
+ if (uri == null) {
+ String directory = required(name, runtime == null ? null : runtime.source().directory().orElse(null),
+ "source.directory");
+ definition = IngestPipelineDefinition.directory(name, directory)
+ .recursive(runtime.source().recursive());
+ } else {
+ definition = IngestPipelineDefinition.consumer(name, uri);
}
- // duplicates skip the block and the tail processor answers SKIPPED; first write wins
- // per id. The EIP keys on the validated id property, evaluating the expression once
- IdempotentRepository repository = resolveRepository(name, repositoryName);
- from(uri)
- .routeId(routeId(name))
- .process(exchange -> exchange.setProperty(DOCUMENT_ID_PROPERTY,
- requireDocumentId(name, documentId, exchange)))
- .idempotentConsumer(exchangeProperty(DOCUMENT_ID_PROPERTY), repository)
- .process(exchange -> {
- String id = (String) exchange.getProperty(DOCUMENT_ID_PROPERTY);
- IngestResult result = service.ingest(id, exchange.getIn().getBody(String.class));
- if (result.outcome() == IngestResult.Outcome.EMPTY) {
- // a blank document wrote nothing, so it must not keep the eager claim
- // on the id - a later, populated delivery under the same id would be
- // answered SKIPPED. The completion-time confirm() of the removed key
- // is a no-op in the memory, file and JDBC repositories alike
- repository.remove(id);
- }
- exchange.getIn().setBody(result);
- })
- .end()
- .process(exchange -> {
- if (exchange.getProperty(Exchange.DUPLICATE_MESSAGE, false, Boolean.class)) {
- exchange.getIn().setBody(new IngestResult(name,
- (String) exchange.getProperty(DOCUMENT_ID_PROPERTY), 0,
- IngestResult.Outcome.SKIPPED));
- }
- });
- }
-
- private static String requireDocumentId(String name, Expression documentId, Exchange exchange) {
- String id = documentId.evaluate(exchange, String.class);
- if (id == null) {
- throw new IllegalArgumentException("Ingestion pipeline '" + name + "': no document id. "
- + "Set the " + IngestHeaders.DOCUMENT_ID + " header, or point "
- + "quarkus.camel.langchain4j.ingest." + name + ".source.document-id at where the "
- + "consumer puts it.");
+ definition.embeddingStore(store)
+ .embeddingModel(model)
+ .splitter(maxSegmentSize, maxOverlapSize)
+ .embeddingBatchSize(embeddingBatchSize);
+ if (maxDocumentSize > 0) {
+ definition.maxDocumentSize(maxDocumentSize);
+ }
+ if (documentSplitterName != null) {
+ definition.documentSplitter(documentSplitterName);
+ }
+ if (parser != null) {
+ definition.parser(parser);
}
- return id;
- }
- @SuppressWarnings("deprecation")
- private Expression documentIdExpression(String name, IngestRunTimeConfig.PipelineRunTimeConfig runtime,
- String defaultHeader) {
- String configured = runtime == null ? null : runtime.source().documentId().orElse(null);
- if (configured == null) {
- if (IngestHeaders.DOCUMENT_ID.equals(defaultHeader)) {
- // the current name first, the 3.39 name as fallback; each name keeps Camel's
- // header-then-exchange-property lookup. The deprecation is warned once per
- // pipeline - literal-setting producers get no compiler signal
- Expression current = ExpressionBuilder.headerExpression(IngestHeaders.DOCUMENT_ID);
- Expression legacy = ExpressionBuilder.headerExpression(IngestHeaders.LEGACY_DOCUMENT_ID);
- current.init(getContext());
- legacy.init(getContext());
- return new ExpressionAdapter() {
- private final AtomicBoolean warned = new AtomicBoolean();
+ String documentId = runtime == null ? null : runtime.source().documentId().orElse(null);
+ if (documentId != null) {
+ definition.documentId(documentId);
+ } else if (uri != null) {
+ // the component's own default since the 3.40 rename (#9162); the 3.39 name is still
+ // read as a fallback in the route builder's documentIdExpression
+ definition.documentId(IngestHeaders.DOCUMENT_ID);
+ }
- @Override
- public Object evaluate(Exchange exchange) {
- Object id = current.evaluate(exchange, Object.class);
- if (id != null) {
- return id;
- }
- id = legacy.evaluate(exchange, Object.class);
- if (id != null && warned.compareAndSet(false, true)) {
- LOG.warnf("Ingestion pipeline '%s': document id read from the deprecated %s name"
- + " - switch the producer to %s",
- name, IngestHeaders.LEGACY_DOCUMENT_ID, IngestHeaders.DOCUMENT_ID);
- }
- return id;
- }
- };
+ String repositoryName = runtime == null ? null : runtime.source().idempotentRepository().orElse(null);
+ boolean autoCreate = runtime != null && runtime.source().idempotentRepositoryAutoCreate();
+ if (autoCreate && repositoryName == null) {
+ throw new IllegalStateException("Ingestion pipeline '" + name
+ + "' sets source.idempotent-repository-auto-create but no "
+ + "source.idempotent-repository name to create the register under.");
+ }
+ if (repositoryName != null) {
+ IdempotentRepository repository = getContext().getRegistry().lookupByNameAndType(repositoryName,
+ IdempotentRepository.class);
+ if (repository == null && !autoCreate) {
+ // the existence check up front, with the configuration-level message
+ throw new IllegalStateException("Ingestion pipeline '" + name
+ + "' references idempotent repository '" + repositoryName + "' but no such bean exists");
}
- return ExpressionBuilder.headerExpression(defaultHeader);
+ if (repository != null) {
+ // whether auto-create is set or not, a pre-existing CDI-produced repository wins
+ // and does not pass through the registry's bind hook, so a CamelContextAware
+ // implementation would otherwise run contextless
+ CamelContextAware.trySetCamelContext(repository, getContext());
+ }
+ definition.idempotentRepository(repositoryName)
+ .idempotentRepositoryAutoCreate(autoCreate);
}
- // a bare header name is read as a header directly rather than parsed: a dotted header
- // name would send the simple parser into OGNL. $simple{...} is the form for a properties
- // file, where MicroProfile Config would consume a ${...} before Camel ever saw it; the
- // ${...} form still serves the Java builder. Both tokens are matched with contains, the
- // same way Camel's own LanguageSupport detects a simple function. The expression is
- // initialised here, at route build time - left to reify lazily it would race on the
- // first concurrent exchanges
- Expression expression = configured.contains("${") || configured.contains("$simple{")
- ? ExpressionBuilder.simpleExpression(configured)
- : ExpressionBuilder.headerExpression(configured);
- expression.init(getContext());
- return expression;
- }
-
- private static String routeId(String name) {
- return "camel-quarkus-langchain4j-ingest-" + name;
+ return definition;
}
private static String required(String name, String value, String property) {
@@ -349,48 +246,6 @@ public class IngestRoutes extends RouteBuilder {
* discovered first. A raw-typed registry search cannot serve here: it never matches a bean
* typed {@code EmbeddingStore<TextSegment>}.
*/
- /**
- * Binds an in-memory register under the configured name, unless a bean with that name
- * already exists — {@code camel.beans.*} beans are bound before route builders run, so both
- * they and CDI beans are visible here and win.
- */
- private void maybeAutoCreateRepository(String name, IngestRunTimeConfig.PipelineRunTimeConfig runtime) {
- if (runtime == null || !runtime.source().idempotentRepositoryAutoCreate()) {
- return;
- }
- String repositoryName = runtime.source().idempotentRepository().orElse(null);
- if (repositoryName == null) {
- throw new IllegalStateException("Ingestion pipeline '" + name
- + "' sets source.idempotent-repository-auto-create but no "
- + "source.idempotent-repository name to create the register under.");
- }
- if (getContext().getRegistry().lookupByNameAndType(repositoryName, IdempotentRepository.class) != null) {
- LOG.infof("Ingestion pipeline '%s': idempotent repository '%s' already exists, auto-create skipped",
- name, repositoryName);
- return;
- }
- getContext().getRegistry().bind(repositoryName,
- MemoryIdempotentRepository.memoryIdempotentRepository(100_000));
- }
-
- /**
- * Resolves the configured register from the Camel registry: CDI producers, camel.beans
- * definitions and auto-created registers alike. By name only — the application may hold
- * unrelated idempotent repositories.
- */
- private IdempotentRepository resolveRepository(String name, String repositoryName) {
- IdempotentRepository repository = getContext().getRegistry().lookupByNameAndType(repositoryName,
- IdempotentRepository.class);
- if (repository == null) {
- throw new IllegalStateException("Ingestion pipeline '" + name + "' references idempotent repository '"
- + repositoryName + "' but no such bean exists");
- }
- // a CDI-produced repository does not pass through the registry's bind hook, so a
- // CamelContextAware implementation would otherwise run contextless
- CamelContextAware.trySetCamelContext(repository, getContext());
- return repository;
- }
-
private <T> T resolve(String name, Instance<T> candidates, String configured, String what, String property) {
if (configured != null) {
Instance<T> named = candidates.select(NamedLiteral.of(configured));
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestService.java b/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestService.java
deleted file mode 100644
index c2061e2714..0000000000
--- a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestService.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.quarkus.component.langchain4j.ingest.core;
-
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import dev.langchain4j.data.document.Document;
-import dev.langchain4j.data.document.DocumentSplitter;
-import dev.langchain4j.data.document.Metadata;
-import dev.langchain4j.data.document.splitter.DocumentSplitters;
-import dev.langchain4j.data.segment.TextSegment;
-import dev.langchain4j.model.embedding.EmbeddingModel;
-import dev.langchain4j.store.embedding.EmbeddingStore;
-import org.jboss.logging.Logger;
-
-/**
- * Splits a document, embeds the segments and writes them to the store.
- *
- * <p>
- * Deliberately naive: it writes whatever it is given and remembers nothing, so ingesting a
- * document twice leaves two copies. Keeping a store in step with a changing source — skipping
- * unchanged documents, replacing changed ones, removing deleted ones — needs a record of what was
- * written, and that engine replaces this class.
- */
-public class IngestService {
-
- private static final Logger LOG = Logger.getLogger(IngestService.class);
-
- // the runtime-neutral names of the camel-langchain4j-ingest component (Camel 4.23), which
- // this engine will delegate to - stores written from 3.40.0 on are compatible with it as-is
- public static final String METADATA_PIPELINE = "camel_ingest_pipeline";
- public static final String METADATA_DOCUMENT_ID = "camel_ingest_document_id";
-
- private static final int EMBEDDING_BATCH_SIZE = 32;
-
- private final String pipeline;
- private final EmbeddingStore<TextSegment> store;
- private final EmbeddingModel model;
- private final DocumentSplitter splitter;
-
- public IngestService(String pipeline, EmbeddingStore<TextSegment> store, EmbeddingModel model,
- int maxSegmentSize, int maxOverlapSize) {
- this.pipeline = pipeline;
- this.store = store;
- this.model = model;
- this.splitter = DocumentSplitters.recursive(maxSegmentSize, maxOverlapSize);
- }
-
- public IngestResult ingest(String documentId, String text) {
- if (documentId == null || documentId.isBlank()) {
- throw new IllegalArgumentException("Ingestion pipeline '" + pipeline + "': documentId is required");
- }
- if (text == null || text.isBlank()) {
- return new IngestResult(pipeline, documentId, 0, IngestResult.Outcome.EMPTY);
- }
-
- // the document id travels with every segment: retrieval can cite it, and the engine that
- // replaces this one needs it to find a document's vectors again
- Map<String, Object> metadata = new LinkedHashMap<>();
- metadata.put(METADATA_PIPELINE, pipeline);
- metadata.put(METADATA_DOCUMENT_ID, documentId);
-
- List<TextSegment> segments = splitter.split(Document.from(text, Metadata.from(metadata)));
- // embedded in batches: a single embedAll over a large document's full segment list can
- // exceed an embedding provider's per-request limits
- for (int from = 0; from < segments.size(); from += EMBEDDING_BATCH_SIZE) {
- List<TextSegment> batch = segments.subList(from, Math.min(from + EMBEDDING_BATCH_SIZE, segments.size()));
- store.addAll(model.embedAll(batch).content(), batch);
- }
-
- LOG.debugf("Ingestion pipeline '%s': wrote %d segment(s) of document '%s'", pipeline, segments.size(),
- documentId);
- return new IngestResult(pipeline, documentId, segments.size(), IngestResult.Outcome.INGESTED);
- }
-
- public String pipeline() {
- return pipeline;
- }
-}
diff --git a/integration-tests/langchain4j-ingest/pom.xml b/integration-tests/langchain4j-ingest/pom.xml
index beca276038..2327378b02 100644
--- a/integration-tests/langchain4j-ingest/pom.xml
+++ b/integration-tests/langchain4j-ingest/pom.xml
@@ -59,10 +59,24 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-kafka</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-docling</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-sql</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tika</artifactId>
+ </dependency>
+ <!-- tika parses only the formats whose parser modules are on the classpath; the reports
+ pipeline ingests PDFs -->
+ <dependency>
+ <groupId>org.apache.tika</groupId>
+ <artifactId>tika-parser-pdf-module</artifactId>
+ </dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
@@ -89,6 +103,11 @@
<artifactId>camel-quarkus-integration-tests-support-kafka</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-integration-wiremock-support</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
@@ -185,6 +204,19 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-docling-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-kafka-deployment</artifactId>
@@ -224,6 +256,19 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-tika-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
</dependencies>
</profile>
</profiles>
diff --git a/integration-tests/langchain4j-ingest/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestItProducers.java b/integration-tests/langchain4j-ingest/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestItProducers.java
index c61430afbc..c93e1fae3f 100644
--- a/integration-tests/langchain4j-ingest/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestItProducers.java
+++ b/integration-tests/langchain4j-ingest/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestItProducers.java
@@ -48,6 +48,34 @@ public class IngestItProducers {
return new InMemoryEmbeddingStore<>();
}
+ @Produces
+ @Singleton
+ @Named("htmlfeed-store")
+ EmbeddingStore<TextSegment> htmlfeedStore() {
+ return new InMemoryEmbeddingStore<>();
+ }
+
+ @Produces
+ @Singleton
+ @Named("reports-store")
+ EmbeddingStore<TextSegment> reportsStore() {
+ return new InMemoryEmbeddingStore<>();
+ }
+
+ @Produces
+ @Singleton
+ @Named("scans-store")
+ EmbeddingStore<TextSegment> scansStore() {
+ return new InMemoryEmbeddingStore<>();
+ }
+
+ @Produces
+ @Singleton
+ @Named("capped-store")
+ EmbeddingStore<TextSegment> cappedStore() {
+ return new InMemoryEmbeddingStore<>();
+ }
+
@Produces
@Singleton
@Named("datasheets-store")
diff --git a/integration-tests/langchain4j-ingest/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestResource.java b/integration-tests/langchain4j-ingest/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestResource.java
index d496f4f474..af14281da2 100644
--- a/integration-tests/langchain4j-ingest/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestResource.java
+++ b/integration-tests/langchain4j-ingest/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestResource.java
@@ -36,9 +36,9 @@ import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.langchain4j.ingest.IngestResult;
+import org.apache.camel.component.langchain4j.ingest.LangChain4jIngest;
import org.apache.camel.quarkus.component.langchain4j.ingest.IngestHeaders;
-import org.apache.camel.quarkus.component.langchain4j.ingest.core.IngestResult;
-import org.apache.camel.quarkus.component.langchain4j.ingest.core.IngestService;
import org.apache.camel.spi.IdempotentRepository;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@@ -57,6 +57,10 @@ public class IngestResource {
@Named("custom-store")
EmbeddingStore<TextSegment> customStore;
+ @Inject
+ @Named("htmlfeed-store")
+ EmbeddingStore<TextSegment> htmlfeedStore;
+
@Inject
@Named("datasheets-store")
EmbeddingStore<TextSegment> datasheetsStore;
@@ -73,6 +77,18 @@ public class IngestResource {
@Named("jdbc-store")
EmbeddingStore<TextSegment> jdbcStore;
+ @Inject
+ @Named("reports-store")
+ EmbeddingStore<TextSegment> reportsStore;
+
+ @Inject
+ @Named("scans-store")
+ EmbeddingStore<TextSegment> scansStore;
+
+ @Inject
+ @Named("capped-store")
+ EmbeddingStore<TextSegment> cappedStore;
+
@Inject
ProducerTemplate producerTemplate;
@@ -82,6 +98,15 @@ public class IngestResource {
@ConfigProperty(name = "ingest.test.directory")
String directory;
+ @ConfigProperty(name = "ingest.reports.directory")
+ String reportsDirectory;
+
+ @ConfigProperty(name = "ingest.scans.directory")
+ String scansDirectory;
+
+ @ConfigProperty(name = "ingest.capped.directory")
+ String cappedDirectory;
+
/** Asserts a key was committed; registry lookup by name, the same way the pipelines resolve. */
@GET
@jakarta.ws.rs.Path("/register-contains")
@@ -102,16 +127,35 @@ public class IngestResource {
Files.writeString(dir.resolve(name), content);
}
+ /** Writes a binary document into a parser pipeline's watched directory. */
+ @POST
+ @jakarta.ws.rs.Path("/binary/{pipeline}/{name}")
+ @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+ public void writeBinary(@PathParam("pipeline") String pipeline, @PathParam("name") String name,
+ byte[] content) throws Exception {
+ Path dir = Path.of(switch (pipeline) {
+ case "scans" -> scansDirectory;
+ case "capped" -> cappedDirectory;
+ default -> reportsDirectory;
+ });
+ Files.createDirectories(dir);
+ Files.write(dir.resolve(name), content);
+ }
+
@GET
@jakarta.ws.rs.Path("/search")
@Produces(MediaType.APPLICATION_JSON)
public List<SearchHit> search(@QueryParam("q") String query, @QueryParam("store") String storeName) {
EmbeddingStore<TextSegment> store = switch (storeName == null ? "products" : storeName) {
case "custom" -> customStore;
+ case "htmlfeed" -> htmlfeedStore;
case "datasheets" -> datasheetsStore;
case "s3" -> s3Store;
case "events" -> eventsStore;
case "jdbc" -> jdbcStore;
+ case "reports" -> reportsStore;
+ case "capped" -> cappedStore;
+ case "scans" -> scansStore;
default -> productsStore;
};
// the deterministic test model gives a query no semantic pull towards any document, so
@@ -125,8 +169,8 @@ public class IngestResource {
return result.matches().stream()
.map(match -> new SearchHit(
match.embedded().text(),
- match.embedded().metadata().getString(IngestService.METADATA_PIPELINE),
- match.embedded().metadata().getString(IngestService.METADATA_DOCUMENT_ID)))
+ match.embedded().metadata().getString(LangChain4jIngest.METADATA_PIPELINE),
+ match.embedded().metadata().getString(LangChain4jIngest.METADATA_DOCUMENT_ID)))
.toList();
}
@@ -175,4 +219,18 @@ public class IngestResource {
return result.outcome().label();
}
+ /** Feeds a pipeline without any document id, so tests can assert the pre-parse id guard. */
+ @POST
+ @jakarta.ws.rs.Path("/feed-anonymous/{pipeline}")
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Produces(MediaType.TEXT_PLAIN)
+ public String feedAnonymous(@PathParam("pipeline") String pipeline, String content) {
+ try {
+ producerTemplate.requestBody("direct:" + pipeline + "-feed", content, IngestResult.class);
+ return "ingested";
+ } catch (Exception e) {
+ return "failed";
+ }
+ }
+
}
diff --git a/integration-tests/langchain4j-ingest/src/main/resources/application.properties b/integration-tests/langchain4j-ingest/src/main/resources/application.properties
index 8a687b1aaa..274beec070 100644
--- a/integration-tests/langchain4j-ingest/src/main/resources/application.properties
+++ b/integration-tests/langchain4j-ingest/src/main/resources/application.properties
@@ -32,6 +32,48 @@ camel.beans.propertiesRegister=\#class\:org.apache.camel.support.processor.idemp
camel.beans.propertiesRegister.cacheSize=5000
quarkus.camel.langchain4j.ingest.products.source.idempotent-repository=propertiesRegister
+# parser pipelines: reports extracts PDF text in-process (tika); scans converts through a
+# Docling Serve instance (docling), which the tests stub with WireMock - see
+# IngestDoclingTestResource. scans stays off until that resource provides the serve URL
+ingest.reports.directory=target/ingest-reports
+quarkus.camel.langchain4j.ingest.reports.source.directory=${ingest.reports.directory}
+quarkus.camel.langchain4j.ingest.reports.parser=tika
+quarkus.camel.langchain4j.ingest.reports.embedding-store=reports-store
+quarkus.camel.langchain4j.ingest.reports.embedding-model=test-model
+quarkus.camel.langchain4j.ingest.reports.max-segment-size=120
+quarkus.camel.langchain4j.ingest.reports.max-overlap-size=20
+
+# parser pipeline with a tight raw-byte cap: exercises the pre-parse size guard
+ingest.capped.directory=target/ingest-capped
+quarkus.camel.langchain4j.ingest.capped.source.directory=${ingest.capped.directory}
+quarkus.camel.langchain4j.ingest.capped.parser=tika
+quarkus.camel.langchain4j.ingest.capped.max-document-size=200
+quarkus.camel.langchain4j.ingest.capped.embedding-store=capped-store
+quarkus.camel.langchain4j.ingest.capped.embedding-model=test-model
+quarkus.camel.langchain4j.ingest.capped.max-segment-size=120
+quarkus.camel.langchain4j.ingest.capped.max-overlap-size=20
+
+ingest.scans.directory=target/ingest-scans
+quarkus.camel.langchain4j.ingest.scans.source.directory=${ingest.scans.directory}
+quarkus.camel.langchain4j.ingest.scans.parser=docling
+quarkus.camel.langchain4j.ingest.scans.embedding-store=scans-store
+quarkus.camel.langchain4j.ingest.scans.embedding-model=test-model
+quarkus.camel.langchain4j.ingest.scans.max-segment-size=120
+quarkus.camel.langchain4j.ingest.scans.max-overlap-size=20
+quarkus.camel.langchain4j.ingest.scans.enabled=false
+
+camel.component.docling.use-docling-serve=true
+camel.component.docling.docling-serve-url=${docling.serve.url:http://localhost:5001}
+
+# consumer-fed pipeline with a parser: the endpoint+parser combination, and the pre-parse
+# document-id capture (a parsed document cannot forge its own id through Tika metadata headers)
+quarkus.camel.langchain4j.ingest.htmlfeed.source.uri=direct:htmlfeed-feed
+quarkus.camel.langchain4j.ingest.htmlfeed.parser=tika
+quarkus.camel.langchain4j.ingest.htmlfeed.embedding-store=htmlfeed-store
+quarkus.camel.langchain4j.ingest.htmlfeed.embedding-model=test-model
+quarkus.camel.langchain4j.ingest.htmlfeed.max-segment-size=120
+quarkus.camel.langchain4j.ingest.htmlfeed.max-overlap-size=20
+
# consumer-fed pipeline; the document-id exercises the $simple{...} form and the register gives
# first-write-wins dedup by document id
quarkus.camel.langchain4j.ingest.custom.source.uri=direct:custom-feed
diff --git a/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestDoclingTestResource.java b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestDoclingTestResource.java
new file mode 100644
index 0000000000..b86d60442b
--- /dev/null
+++ b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/IngestDoclingTestResource.java
@@ -0,0 +1,87 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.it;
+
+import java.util.Map;
+
+import com.github.tomakehurst.wiremock.WireMockServer;
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import org.apache.camel.quarkus.test.mock.backend.MockBackendUtils;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.post;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
+
+/**
+ * Provides the Docling Serve endpoint for the {@code scans} pipeline and switches the pipeline
+ * on. By default the docling-serve convert API is stubbed with an in-process WireMock server —
+ * the real container image is a multi-gigabyte download, about 5 GB compressed for the pinned
+ * v1.29.0 — and answers every conversion with the sentence
+ * {@link Langchain4jIngestDoclingTest} ingests. The real container starts only with
+ * {@code -Dcamel.quarkus.start-mock-backend=false}, the same convention the docling integration
+ * tests use; the test document carries the same sentence, so the assertions hold there too.
+ */
+public class IngestDoclingTestResource implements QuarkusTestResourceLifecycleManager {
+
+ static final String CONVERTED_MARKDOWN = "The EPSILON-2 valve seals at 80 bar.";
+
+ private static final int CONTAINER_PORT = 5001;
+
+ private WireMockServer server;
+ private GenericContainer<?> container;
+
+ @Override
+ public Map<String, String> start() {
+ String doclingServeUrl;
+ if (MockBackendUtils.startMockBackend()) {
+ server = new WireMockServer(WireMockConfiguration.options().dynamicPort());
+ server.stubFor(post(urlEqualTo("/v1/convert/source"))
+ .willReturn(aResponse()
+ .withHeader("Content-Type", "application/json")
+ .withBody("{\"document\":{\"filename\":\"valve.pdf\",\"md_content\":\""
+ + CONVERTED_MARKDOWN + "\",\"json_content\":null,\"html_content\":null,"
+ + "\"text_content\":null,\"doctags_content\":null},\"status\":\"success\","
+ + "\"errors\":[],\"processing_time\":0.01,\"timings\":{}}")));
+ server.start();
+ doclingServeUrl = "http://localhost:" + server.port();
+ } else {
+ container = new GenericContainer<>(
+ ConfigProvider.getConfig().getValue("docling.container.image", String.class))
+ .withExposedPorts(CONTAINER_PORT)
+ .waitingFor(Wait.forListeningPort());
+ container.start();
+ doclingServeUrl = "http://" + container.getHost() + ":" + container.getMappedPort(CONTAINER_PORT);
+ }
+ return Map.of(
+ "docling.serve.url", doclingServeUrl,
+ "quarkus.camel.langchain4j.ingest.scans.enabled", "true");
+ }
+
+ @Override
+ public void stop() {
+ if (server != null) {
+ server.stop();
+ }
+ if (container != null) {
+ container.stop();
+ }
+ }
+}
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestResult.java b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestDoclingIT.java
similarity index 57%
copy from extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestResult.java
copy to integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestDoclingIT.java
index 45e4d86799..40b4af8759 100644
--- a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestResult.java
+++ b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestDoclingIT.java
@@ -14,26 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.quarkus.component.langchain4j.ingest.core;
+package org.apache.camel.quarkus.component.langchain4j.ingest.it;
-import java.util.Locale;
+import io.quarkus.test.junit.QuarkusIntegrationTest;
-/**
- * Outcome of one ingestion.
- */
-public record IngestResult(String pipeline, String documentId, int segmentsWritten, Outcome outcome) {
-
- public enum Outcome {
- /** Segments written. */
- INGESTED,
- /** Blank document, nothing written. */
- EMPTY,
- /** Already ingested under the same key, nothing written. */
- SKIPPED;
-
- /** The stable wire/log form. */
- public String label() {
- return name().toLowerCase(Locale.ROOT);
- }
- }
+@QuarkusIntegrationTest
+class Langchain4jIngestDoclingIT extends Langchain4jIngestDoclingTest {
}
diff --git a/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestDoclingTest.java b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestDoclingTest.java
new file mode 100644
index 0000000000..33546585e1
--- /dev/null
+++ b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestDoclingTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.it;
+
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * The {@code docling} parser: a PDF dropped into the watched directory is converted to markdown
+ * by docling-serve — stubbed with WireMock by default, see {@link IngestDoclingTestResource} —
+ * and the markdown is ingested. The checked-in fixture carries the same sentence the stub
+ * returns, so the test also holds against a real docling-serve
+ * ({@code -Dcamel.quarkus.start-mock-backend=false}).
+ */
+@QuarkusTest
+@QuarkusTestResource(value = IngestDoclingTestResource.class, restrictToAnnotatedClass = true)
+class Langchain4jIngestDoclingTest {
+
+ @Test
+ void documentIsConvertedAndIngested() throws Exception {
+ RestAssured.given().contentType(ContentType.BINARY)
+ .body(getClass().getResourceAsStream("/valve.pdf").readAllBytes())
+ .post("/langchain4j-ingest/binary/scans/valve.pdf")
+ .then().statusCode(204);
+
+ Awaitility.await().atMost(60, TimeUnit.SECONDS).pollInterval(500, TimeUnit.MILLISECONDS)
+ .untilAsserted(() -> {
+ Map<String, String> hit = Langchain4jIngestTest.hit(
+ "At what pressure does the valve seal?", "scans", "EPSILON-2");
+ assertNotNull(hit, "the document must be converted and its markdown ingested");
+ assertEquals("scans", hit.get("pipeline"));
+ assertEquals("valve.pdf", hit.get("documentId"));
+ });
+ }
+}
diff --git a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestResult.java b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestTikaIT.java
similarity index 57%
rename from extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestResult.java
rename to integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestTikaIT.java
index 45e4d86799..4e3bdcc787 100644
--- a/extensions/langchain4j-ingest/runtime/src/main/java/org/apache/camel/quarkus/component/langchain4j/ingest/core/IngestResult.java
+++ b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestTikaIT.java
@@ -14,26 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.quarkus.component.langchain4j.ingest.core;
+package org.apache.camel.quarkus.component.langchain4j.ingest.it;
-import java.util.Locale;
+import io.quarkus.test.junit.QuarkusIntegrationTest;
-/**
- * Outcome of one ingestion.
- */
-public record IngestResult(String pipeline, String documentId, int segmentsWritten, Outcome outcome) {
-
- public enum Outcome {
- /** Segments written. */
- INGESTED,
- /** Blank document, nothing written. */
- EMPTY,
- /** Already ingested under the same key, nothing written. */
- SKIPPED;
-
- /** The stable wire/log form. */
- public String label() {
- return name().toLowerCase(Locale.ROOT);
- }
- }
+@QuarkusIntegrationTest
+class Langchain4jIngestTikaIT extends Langchain4jIngestTikaTest {
}
diff --git a/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestTikaTest.java b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestTikaTest.java
new file mode 100644
index 0000000000..a660a90e9d
--- /dev/null
+++ b/integration-tests/langchain4j-ingest/src/test/java/org/apache/camel/quarkus/component/langchain4j/ingest/it/Langchain4jIngestTikaTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.quarkus.component.langchain4j.ingest.it;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The {@code tika} parser: a PDF dropped into the watched directory is parsed to text in-process
+ * and ingested like any text file, the file name as the document id. The fixture is a checked-in
+ * one-page PDF carrying the asserted sentence, the same pattern the tika and docling test
+ * modules use.
+ */
+@QuarkusTest
+class Langchain4jIngestTikaTest {
+
+ @Test
+ void pdfIsParsedAndIngested() throws Exception {
+ RestAssured.given().contentType(ContentType.BINARY)
+ .body(getClass().getResourceAsStream("/pump.pdf").readAllBytes())
+ .post("/langchain4j-ingest/binary/reports/pump.pdf")
+ .then().statusCode(204);
+
+ // generous on purpose: the first PDF parse on a fresh machine builds PDFBox's on-disk
+ // font cache (the fixture's non-embedded Helvetica consults the system font provider),
+ // which alone exceeds the usual timeout on Windows CI runners
+ Awaitility.await().atMost(3, TimeUnit.MINUTES).pollInterval(500, TimeUnit.MILLISECONDS)
+ .untilAsserted(() -> {
+ Map<String, String> hit = Langchain4jIngestTest.hit(
+ "What does the pump tolerate?", "reports", "DELTA-5");
+ assertNotNull(hit, "the PDF must be parsed and its text ingested");
+ assertEquals("reports", hit.get("pipeline"));
+ assertEquals("pump.pdf", hit.get("documentId"));
+ });
+ }
+
+ /**
+ * A structured format (HTML, from the parser module camel-tika itself ships): adjacent block
+ * elements must not glue into one word in the extracted text, and the {@code <head><title>}
+ * must not be ingested — Tika's text output keeps the body subtree only. The fixture keeps
+ * its two paragraphs adjacent with no whitespace between them, so any separation comes from
+ * the parse, not from the fixture's own formatting.
+ */
+ @Test
+ void htmlBlocksStaySeparatedAndTitleIsDropped() throws Exception {
+ RestAssured.given().contentType(ContentType.BINARY)
+ .body(getClass().getResourceAsStream("/notice.html").readAllBytes())
+ .post("/langchain4j-ingest/binary/reports/notice.html")
+ .then().statusCode(204);
+
+ Awaitility.await().atMost(30, TimeUnit.SECONDS).pollInterval(500, TimeUnit.MILLISECONDS)
+ .untilAsserted(() -> assertNotNull(
+ Langchain4jIngestTest.hit("What opens the second paragraph?", "reports", "OMEGA-3"),
+ "the HTML must be parsed and its text ingested"));
+
+ List<Map<String, String>> hits = Langchain4jIngestTest.hits("maintenance notice", "reports");
+ // both paragraphs fit one segment, so the glue check is exercised within a single text
+ assertTrue(hits.stream().anyMatch(
+ hit -> hit.get("text").contains("GAMMA-7") && hit.get("text").contains("OMEGA-3")),
+ "both paragraphs must land in one segment");
+ assertTrue(hits.stream().noneMatch(hit -> hit.get("text").contains("GAMMA-7OMEGA-3")),
+ "adjacent block elements must stay separated in the extracted text");
+ assertTrue(hits.stream().noneMatch(hit -> hit.get("text").contains("Should not be ingested")),
+ "the title must not be ingested");
+ }
+
+ /**
+ * The endpoint+parser combination, and the anti-spoofing contract with it: Tika copies a
+ * document's {@code <meta>} entries over the exchange headers, so the document id must have
+ * been captured before the parse — a document claiming another id through its own metadata
+ * ingests under the identity the consumer delivered, not the forged one.
+ */
+ @Test
+ void consumerFedParserCannotBeIdSpoofed() {
+ RestAssured.given().contentType(ContentType.TEXT)
+ .body("<html><head><meta name=\"CamelIngestDocumentId\" content=\"spoofed.txt\"/>"
+ + "<title>Should not be ingested</title></head>"
+ + "<body><p>The PSI-9 relay arrives over the feed.</p></body></html>")
+ .post("/langchain4j-ingest/feed/htmlfeed/real.html")
+ .then().statusCode(200).body(org.hamcrest.Matchers.is("ingested"));
+
+ Map<String, String> hit = Langchain4jIngestTest.hit("What arrives over the feed?", "htmlfeed", "PSI-9");
+ assertNotNull(hit, "the HTML must be parsed and its text ingested");
+ assertEquals("real.html", hit.get("documentId"),
+ "the id must be the one the consumer delivered, not the document's forgery");
+ assertTrue(Langchain4jIngestTest.hits("relay", "htmlfeed").stream()
+ .noneMatch(h -> "spoofed.txt".equals(h.get("documentId"))),
+ "nothing may be ingested under the forged id");
+ }
+
+ /**
+ * The pre-parse raw-byte guard: on the {@code capped} pipeline ({@code max-document-size=200})
+ * a small document ingests — proving the pipeline is live — while an oversized one is
+ * rejected before it reaches the parser and never lands in the store; its register key stays
+ * uncommitted, so the file is retried (and rejected again) on every poll.
+ */
+ @Test
+ void oversizedDocumentIsRejectedBeforeTheParser() throws Exception {
+ RestAssured.given().contentType(ContentType.BINARY)
+ .body("<html><body><p>KAPPA-1 fits under the cap.</p></body></html>"
+ .getBytes(java.nio.charset.StandardCharsets.UTF_8))
+ .post("/langchain4j-ingest/binary/capped/small.html")
+ .then().statusCode(204);
+
+ Awaitility.await().atMost(30, TimeUnit.SECONDS).pollInterval(500, TimeUnit.MILLISECONDS)
+ .untilAsserted(() -> assertNotNull(
+ Langchain4jIngestTest.hit("What fits under the cap?", "capped", "KAPPA-1"),
+ "the small document must be parsed and ingested"));
+
+ // pump.pdf is ~850 bytes, well over the 200-byte cap
+ RestAssured.given().contentType(ContentType.BINARY)
+ .body(getClass().getResourceAsStream("/pump.pdf").readAllBytes())
+ .post("/langchain4j-ingest/binary/capped/pump.pdf")
+ .then().statusCode(204);
+
+ // the absence must hold across several poll cycles, not just at one instant
+ Awaitility.await().during(3, TimeUnit.SECONDS).atMost(10, TimeUnit.SECONDS)
+ .until(() -> Langchain4jIngestTest.hits("What does the pump tolerate?", "capped").stream()
+ .noneMatch(hit -> hit.get("text").contains("DELTA-5")));
+ }
+
+ /**
+ * A delivery whose document id resolves to nothing must fail before the parse: with the
+ * exchange property unset, the producer's header fallback would read headers a parsed
+ * document may have written — the previous engine failed such a delivery too.
+ */
+ @Test
+ void consumerDeliveryWithoutIdFailsBeforeTheParse() {
+ RestAssured.given().contentType(ContentType.TEXT)
+ .body("<html><head><meta name=\"CamelIngestDocumentId\" content=\"anonymous-victim.txt\"/></head>"
+ + "<body><p>The RHO-4 module arrives without an id.</p></body></html>")
+ .post("/langchain4j-ingest/feed-anonymous/htmlfeed")
+ .then().statusCode(200).body(org.hamcrest.Matchers.is("failed"));
+
+ assertTrue(Langchain4jIngestTest.hits("module arrives", "htmlfeed").stream()
+ .noneMatch(hit -> hit.get("text").contains("RHO-4")),
+ "nothing may be ingested from an id-less delivery");
+ }
+
+ /** The same anti-spoofing contract on a directory pipeline: the file name wins. */
+ @Test
+ void directoryDocumentCannotSpoofItsId() {
+ RestAssured.given().contentType(ContentType.BINARY)
+ .body(("<html><head><meta name=\"CamelFileName\" content=\"forged.txt\"/></head>"
+ + "<body><p>The CHI-3 sensor sits in an honest file.</p></body></html>")
+ .getBytes(java.nio.charset.StandardCharsets.UTF_8))
+ .post("/langchain4j-ingest/binary/reports/honest.html")
+ .then().statusCode(204);
+
+ Awaitility.await().atMost(30, TimeUnit.SECONDS).pollInterval(500, TimeUnit.MILLISECONDS)
+ .untilAsserted(() -> {
+ Map<String, String> hit = Langchain4jIngestTest.hit(
+ "Where does the sensor sit?", "reports", "CHI-3");
+ assertNotNull(hit, "the HTML must be parsed and its text ingested");
+ assertEquals("honest.html", hit.get("documentId"),
+ "the id must be the file name, not the document's forgery");
+ });
+ }
+}
diff --git a/integration-tests/langchain4j-ingest/src/test/resources/notice.html b/integration-tests/langchain4j-ingest/src/test/resources/notice.html
new file mode 100644
index 0000000000..3148175750
--- /dev/null
+++ b/integration-tests/langchain4j-ingest/src/test/resources/notice.html
@@ -0,0 +1,22 @@
+<!--
+
+ 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.
+
+-->
+<html>
+<head><title>Should not be ingested</title></head>
+<body><p>The maintenance notice ends its first paragraph with GAMMA-7</p><p>OMEGA-3 opens the second paragraph of the notice.</p></body>
+</html>
diff --git a/integration-tests/langchain4j-ingest/src/test/resources/pump.pdf b/integration-tests/langchain4j-ingest/src/test/resources/pump.pdf
new file mode 100644
index 0000000000..110d9e6093
Binary files /dev/null and b/integration-tests/langchain4j-ingest/src/test/resources/pump.pdf differ
diff --git a/integration-tests/langchain4j-ingest/src/test/resources/valve.pdf b/integration-tests/langchain4j-ingest/src/test/resources/valve.pdf
new file mode 100644
index 0000000000..dfc8aeefc6
Binary files /dev/null and b/integration-tests/langchain4j-ingest/src/test/resources/valve.pdf differ
diff --git a/pom.xml b/pom.xml
index 9ee8fc5f5b..33585ae5f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -194,6 +194,7 @@
<microsoft.graph.auth.version>0.3.0</microsoft.graph.auth.version>
<pdfbox.version>${pdfbox-version}</pdfbox.version>
<sshd.version>2.19.0</sshd.version><!-- @sync io.quarkus:quarkus-bom:${quarkus.version} dep:org.apache.sshd:sshd-common -->
+ <tika.version>${tika-version}</tika.version>
<unboundid-ldapsdk.version>7.0.5</unboundid-ldapsdk.version>
<wiremock.version>3.13.2</wiremock.version>
<xmlunit.version>2.14.0</xmlunit.version>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index 6b857bc4b2..33645584ea 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -2220,6 +2220,11 @@
<artifactId>camel-langchain4j-embeddingstore-api</artifactId>
<version>${camel.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-langchain4j-ingest</artifactId>
+ <version>${camel.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-langchain4j-tokenizer</artifactId>
@@ -8359,6 +8364,17 @@
<artifactId>shiro-core</artifactId>
<version>${shiro-version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.tika</groupId>
+ <artifactId>tika-parser-pdf-module</artifactId>
+ <version>${tika.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>xmlgraphics-commons</artifactId>
@@ -8732,6 +8748,10 @@
<resolutionEntryPointInclude>com.ibm.icu:icu4j</resolutionEntryPointInclude>
<resolutionEntryPointInclude>com.sun.xml.fastinfoset:FastInfoset</resolutionEntryPointInclude>
<resolutionEntryPointInclude>org.mapstruct:mapstruct-processor</resolutionEntryPointInclude>
+ <!-- Tika parses only the formats whose parser modules are present; applications
+ using the langchain4j-ingest tika parser add the modules for their formats;
+ moves to camel-quarkus-tika together with the native build steps, see #9087 -->
+ <resolutionEntryPointInclude>org.apache.tika:tika-parser-pdf-module</resolutionEntryPointInclude>
</resolutionEntryPointIncludes>
<resolutionExcludes>
<!-- Exclude artifacts that we do not want in the flattened BOM -->
diff --git a/poms/bom/src/main/generated/flattened-full-pom.xml b/poms/bom/src/main/generated/flattened-full-pom.xml
index 12a22df02f..6db340970d 100644
--- a/poms/bom/src/main/generated/flattened-full-pom.xml
+++ b/poms/bom/src/main/generated/flattened-full-pom.xml
@@ -2133,6 +2133,11 @@
<artifactId>camel-langchain4j-embeddingstore-api</artifactId>
<version>4.22.1</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-langchain4j-ingest</artifactId>
+ <version>4.23.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-langchain4j-tokenizer</artifactId>
@@ -8241,6 +8246,17 @@
<artifactId>shiro-core</artifactId>
<version>3.0.0</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.tika</groupId>
+ <artifactId>tika-parser-pdf-module</artifactId>
+ <version>4.0.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>xmlgraphics-commons</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-reduced-pom.xml b/poms/bom/src/main/generated/flattened-reduced-pom.xml
index 1f95524335..d530976560 100644
--- a/poms/bom/src/main/generated/flattened-reduced-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-pom.xml
@@ -3476,6 +3476,11 @@
<artifactId>camel-langchain4j-embeddingstore-api</artifactId>
<version>4.22.1</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-langchain4j-ingest</artifactId>
+ <version>4.23.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-langchain4j-tokenizer</artifactId>
@@ -9055,6 +9060,17 @@
<artifactId>shiro-core</artifactId>
<version>3.0.0</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.tika</groupId>
+ <artifactId>tika-parser-pdf-module</artifactId>
+ <version>4.0.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
index e507894b88..75e1b11601 100644
--- a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
@@ -3476,6 +3476,11 @@
<artifactId>camel-langchain4j-embeddingstore-api</artifactId>
<version>4.22.1</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-langchain4j-ingest</artifactId>
+ <version>4.23.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-langchain4j-tokenizer</artifactId>
@@ -9055,6 +9060,17 @@
<artifactId>shiro-core</artifactId>
<version>3.0.0</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.tika</groupId>
+ <artifactId>tika-parser-pdf-module</artifactId>
+ <version>4.0.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
(camel-quarkus) 02/04: CAMEL-25197: cli-connector - use the Vert.x WebSocket client for the WebSocket transport
Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
JiriOndrusek pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 028d4b0b344c48fc918c96ed02bea78130564a16
Author: Federico Mariani <34...@users.noreply.github.com>
AuthorDate: Thu Oct 1 19:44:21 2026 +0200
CAMEL-25197: cli-connector - use the Vert.x WebSocket client for the WebSocket transport
* CAMEL-25197: cli-connector - use the Quarkus WebSockets Next client for the WebSocket transport
When the application has quarkus-websockets-next, the Camel CLI connector WebSocket transport
(camel.cli.transport=websocket) uses its client through the new CliWebSocketClient SPI of
camel-cli-connector, otherwise the JDK client. No dependency is added to the application for this:
quarkus-websockets-next is an optional dependency, and the client bean is only registered when the
capability is present.
- QuarkusCliWebSocketClient: BasicWebSocketConnector, non-blocking callbacks on the event loop, 16 MB
messages, 64 KB frames, path and query sent as given, handshake rejections mapped to their HTTP status
- quarkus.camel.cli.websocket.tls-configuration-name (runtime) selects a TLS registry configuration
- workarounds for WebSockets Next 3.40: back-pressure disabled by default
(quarkus.websockets-next.client.max-pending-messages=0, it stalls connections receiving fragmented
messages), and no onClose callback (a 1006 close fails in WebSockets Next and skips the cleanup)
- integration tests for both clients: cli-connector (JDK) and cli-connector-websockets-next, sharing the
test application and a WebSocket tool server
Co-Authored-By: Claude Opus 5.5 <no...@anthropic.com>
* CAMEL-25197: cli-connector - use the Vert.x WebSocket client, refuse the WebSocket transport in prod
Review follow-up:
- the Vert.x WebSocket client of the application replaces the WebSockets Next client, and is the default
on Camel Quarkus (camel.cli.websocket.client=jdk uses the JDK client): no optional dependency, no
application-wide back-pressure setting, close status and raw request uri as given, a real abort
- connect and handshake timeouts of 10 s, as the JDK client
- whole messages accepted in a single frame (sizes in bytes), messages sent in frames of 64 KB at most
- the WebSocket transport is refused with the Quarkus prod profile: Camel Quarkus only sets the Camel
profile in dev mode, so the Camel prod profile check did not apply to packaged applications
- tests: a 1 MB action in a single frame, a tool that does not answer the handshake, the prod profile
(QuarkusProdModeTest); unused rest-assured removed
Co-Authored-By: Claude Opus 5.5 <no...@anthropic.com>
* CAMEL-25197: cli-connector - match the transport name in any case, apply the whole TLS configuration
- the Quarkus prod profile guard matches camel.cli.transport in any case, as Camel does
- the TLS registry configuration is applied with TlsConfigUtils (cipher suites, protocols, CRLs, ...)
Co-Authored-By: Claude Opus 5.5 <no...@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <no...@anthropic.com>
---
.../pages/reference/extensions/cli-connector.adoc | 37 ++++
extensions-jvm/cli-connector/deployment/pom.xml | 4 +
.../deployment/CliConnectorProcessor.java | 15 ++
.../CliConnectorWebSocketProdProfileTest.java | 48 +++++
extensions-jvm/cli-connector/runtime/pom.xml | 4 +
.../cli-connector/runtime/src/main/doc/usage.adoc | 24 +++
.../connector/CamelCliConnectorRunTimeConfig.java | 45 +++++
.../cli/connector/QuarkusLocalCliConnector.java | 15 ++
.../cli/connector/VertxCliWebSocketClient.java | 198 +++++++++++++++++++++
integration-tests-jvm/cli-connector/pom.xml | 28 ++-
.../cli/connector/it/CliConnectorResource.java | 47 -----
.../cli/connector/it/CliConnectorRoutes.java} | 19 +-
.../src/main/resources/application.properties | 25 +++
.../cli/connector/it/CliConnectorTest.java | 139 ++++++++++++++-
.../component/cli/connector/it/CliToolServer.java | 164 +++++++++++++++++
15 files changed, 741 insertions(+), 71 deletions(-)
diff --git a/docs/modules/ROOT/pages/reference/extensions/cli-connector.adoc b/docs/modules/ROOT/pages/reference/extensions/cli-connector.adoc
index 55c74a4c75..c5152000f6 100644
--- a/docs/modules/ROOT/pages/reference/extensions/cli-connector.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/cli-connector.adoc
@@ -40,6 +40,36 @@ ifeval::[{doc-show-user-guide-link} == true]
Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
endif::[]
+[id="extensions-cli-connector-usage"]
+== Usage
+[id="extensions-cli-connector-usage-websocket-transport"]
+=== WebSocket transport
+
+With `camel.cli.transport=websocket`, the application dials out to a developer tool over a WebSocket instead of
+exchanging files with the Camel CLI (see the
+xref:{cq-camel-components}:others:cli-connector.adoc[CLI Connector] documentation for the protocol and the options).
+
+[source,properties]
+----
+%dev.camel.cli.transport = websocket
+%dev.camel.cli.websocket.url = ws://127.0.0.1:8000/connect?executionId=run-1
+----
+
+The tool gets full control of the application: the transport refuses to start with the Quarkus `prod` profile (the
+default profile of a packaged application), as with the Camel `prod` profile (`camel.main.profile=prod`). To use it
+from a packaged application, for example on a remote development cluster, run it with another profile.
+
+[id="extensions-cli-connector-usage-websocket-client"]
+==== WebSocket client
+
+The connector uses the Vert.x WebSocket client of the application. The client in use is logged at startup
+(`Camel CLI connector uses the vertx WebSocket client`) and reported to the tool. Set
+`camel.cli.websocket.client=jdk` to use the JDK WebSocket client instead.
+
+For a `wss://` tool, `quarkus.camel.cli.websocket.tls-configuration-name` selects a TLS configuration of the
+https://quarkus.io/guides/tls-registry-reference[Quarkus TLS registry]; otherwise the JVM default trust store is used.
+
+
[id="extensions-cli-connector-additional-camel-quarkus-configuration"]
== Additional Camel Quarkus configuration
@@ -53,6 +83,13 @@ a|icon:lock[title=Fixed at build time] [[quarkus-camel-cli-enabled]]`link:#quark
Sets whether to enable Camel CLI Connector support.
| `boolean`
| `true`
+
+a| [[quarkus-camel-cli-websocket-tls-configuration-name]]`link:#quarkus-camel-cli-websocket-tls-configuration-name[quarkus.camel.cli.websocket.tls-configuration-name]`
+
+The name of the TLS configuration (from the Quarkus TLS registry) used to connect to a `wss://` tool. When
+not set, the JVM default trust store is used.
+| `string`
+|
|===
[.configuration-legend]
diff --git a/extensions-jvm/cli-connector/deployment/pom.xml b/extensions-jvm/cli-connector/deployment/pom.xml
index 4ecc63428c..47cbf556e0 100644
--- a/extensions-jvm/cli-connector/deployment/pom.xml
+++ b/extensions-jvm/cli-connector/deployment/pom.xml
@@ -46,6 +46,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-cli-connector</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-vertx-http-deployment</artifactId>
+ </dependency>
<dependency>
<groupId>io.quarkus</groupId>
diff --git a/extensions-jvm/cli-connector/deployment/src/main/java/org/apache/camel/quarkus/component/cli/connector/deployment/CliConnectorProcessor.java b/extensions-jvm/cli-connector/deployment/src/main/java/org/apache/camel/quarkus/component/cli/connector/deployment/CliConnectorProcessor.java
index 8461d504f3..1564b1ec62 100644
--- a/extensions-jvm/cli-connector/deployment/src/main/java/org/apache/camel/quarkus/component/cli/connector/deployment/CliConnectorProcessor.java
+++ b/extensions-jvm/cli-connector/deployment/src/main/java/org/apache/camel/quarkus/component/cli/connector/deployment/CliConnectorProcessor.java
@@ -18,6 +18,8 @@ package org.apache.camel.quarkus.component.cli.connector.deployment;
import java.util.function.BooleanSupplier;
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.processor.DotNames;
import io.quarkus.builder.Version;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
@@ -27,6 +29,7 @@ import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import org.apache.camel.quarkus.component.cli.connector.CamelCliConnectorConfig;
import org.apache.camel.quarkus.component.cli.connector.CamelCliConnectorRecorder;
+import org.apache.camel.quarkus.component.cli.connector.VertxCliWebSocketClient;
import org.apache.camel.quarkus.core.JvmOnlyRecorder;
import org.apache.camel.quarkus.core.deployment.spi.CamelBeanBuildItem;
import org.apache.camel.spi.CliConnectorFactory;
@@ -51,6 +54,18 @@ class CliConnectorProcessor {
recorder.createCliConnectorFactory(Version.getVersion()));
}
+ /**
+ * The WebSocket transport uses the Vert.x client, unless camel.cli.websocket.client=jdk.
+ */
+ @BuildStep
+ AdditionalBeanBuildItem webSocketClient() {
+ return AdditionalBeanBuildItem.builder()
+ .addBeanClasses(VertxCliWebSocketClient.class)
+ .setDefaultScope(DotNames.SINGLETON)
+ .setUnremovable()
+ .build();
+ }
+
/**
* Remove this once this extension starts supporting the native mode.
*/
diff --git a/extensions-jvm/cli-connector/deployment/src/test/java/org/apache/camel/quarkus/component/cli/connector/deployment/CliConnectorWebSocketProdProfileTest.java b/extensions-jvm/cli-connector/deployment/src/test/java/org/apache/camel/quarkus/component/cli/connector/deployment/CliConnectorWebSocketProdProfileTest.java
new file mode 100644
index 0000000000..f6b871d2ea
--- /dev/null
+++ b/extensions-jvm/cli-connector/deployment/src/test/java/org/apache/camel/quarkus/component/cli/connector/deployment/CliConnectorWebSocketProdProfileTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.quarkus.component.cli.connector.deployment;
+
+import java.util.Map;
+
+import io.quarkus.test.QuarkusProdModeTest;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class CliConnectorWebSocketProdProfileTest {
+ // a packaged application: the Quarkus prod profile
+ @RegisterExtension
+ static final QuarkusProdModeTest CONFIG = new QuarkusProdModeTest()
+ .withEmptyApplication()
+ .setApplicationName("cli-connector-prod")
+ .setApplicationVersion("1.0")
+ .setRun(true)
+ .setExpectExit(true)
+ .setRuntimeProperties(Map.of(
+ // any case, as Camel matches it
+ "camel.cli.transport", "WebSocket",
+ "camel.cli.websocket.url", "ws://127.0.0.1:9/connect"));
+
+ @Test
+ void refusesTheWebSocketTransport() {
+ String output = CONFIG.getStartupConsoleOutput();
+ assertTrue(output.contains("cannot be used with the Quarkus prod profile"), output);
+ assertNotEquals(0, CONFIG.getExitCode());
+ }
+}
diff --git a/extensions-jvm/cli-connector/runtime/pom.xml b/extensions-jvm/cli-connector/runtime/pom.xml
index 3e2a535579..084176c02e 100644
--- a/extensions-jvm/cli-connector/runtime/pom.xml
+++ b/extensions-jvm/cli-connector/runtime/pom.xml
@@ -51,6 +51,10 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-cli-connector</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-vertx-http</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git a/extensions-jvm/cli-connector/runtime/src/main/doc/usage.adoc b/extensions-jvm/cli-connector/runtime/src/main/doc/usage.adoc
new file mode 100644
index 0000000000..2a3f07e2d6
--- /dev/null
+++ b/extensions-jvm/cli-connector/runtime/src/main/doc/usage.adoc
@@ -0,0 +1,24 @@
+=== WebSocket transport
+
+With `camel.cli.transport=websocket`, the application dials out to a developer tool over a WebSocket instead of
+exchanging files with the Camel CLI (see the
+xref:{cq-camel-components}:others:cli-connector.adoc[CLI Connector] documentation for the protocol and the options).
+
+[source,properties]
+----
+%dev.camel.cli.transport = websocket
+%dev.camel.cli.websocket.url = ws://127.0.0.1:8000/connect?executionId=run-1
+----
+
+The tool gets full control of the application: the transport refuses to start with the Quarkus `prod` profile (the
+default profile of a packaged application), as with the Camel `prod` profile (`camel.main.profile=prod`). To use it
+from a packaged application, for example on a remote development cluster, run it with another profile.
+
+==== WebSocket client
+
+The connector uses the Vert.x WebSocket client of the application. The client in use is logged at startup
+(`Camel CLI connector uses the vertx WebSocket client`) and reported to the tool. Set
+`camel.cli.websocket.client=jdk` to use the JDK WebSocket client instead.
+
+For a `wss://` tool, `quarkus.camel.cli.websocket.tls-configuration-name` selects a TLS configuration of the
+https://quarkus.io/guides/tls-registry-reference[Quarkus TLS registry]; otherwise the JVM default trust store is used.
diff --git a/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/CamelCliConnectorRunTimeConfig.java b/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/CamelCliConnectorRunTimeConfig.java
new file mode 100644
index 0000000000..0de5cef305
--- /dev/null
+++ b/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/CamelCliConnectorRunTimeConfig.java
@@ -0,0 +1,45 @@
+/*
+ * 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.quarkus.component.cli.connector;
+
+import java.util.Optional;
+
+import io.quarkus.runtime.annotations.ConfigPhase;
+import io.quarkus.runtime.annotations.ConfigRoot;
+import io.smallrye.config.ConfigMapping;
+
+@ConfigRoot(phase = ConfigPhase.RUN_TIME)
+@ConfigMapping(prefix = "quarkus.camel.cli")
+public interface CamelCliConnectorRunTimeConfig {
+ /**
+ * Options of the WebSocket transport (`camel.cli.transport=websocket`) when the Vert.x client is used (the
+ * default).
+ *
+ * @asciidoclet
+ */
+ WebSocketConfig websocket();
+
+ interface WebSocketConfig {
+ /**
+ * The name of the TLS configuration (from the Quarkus TLS registry) used to connect to a `wss://` tool. When
+ * not set, the JVM default trust store is used.
+ *
+ * @asciidoclet
+ */
+ Optional<String> tlsConfigurationName();
+ }
+}
diff --git a/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/QuarkusLocalCliConnector.java b/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/QuarkusLocalCliConnector.java
index d8fb9f4e22..f3db169b22 100644
--- a/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/QuarkusLocalCliConnector.java
+++ b/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/QuarkusLocalCliConnector.java
@@ -18,6 +18,8 @@ package org.apache.camel.quarkus.component.cli.connector;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.Quarkus;
+import io.quarkus.runtime.configuration.ConfigUtils;
+import org.apache.camel.cli.connector.CliConnectorTransport;
import org.apache.camel.cli.connector.LocalCliConnector;
import org.apache.camel.spi.CliConnectorFactory;
@@ -26,6 +28,19 @@ public class QuarkusLocalCliConnector extends LocalCliConnector {
super(cliConnectorFactory);
}
+ @Override
+ protected CliConnectorTransport createTransport(String name) {
+ // Camel refuses it with the Camel prod profile, which Camel Quarkus does not set outside dev mode
+ // matched as Camel does (any case)
+ if ("websocket".equalsIgnoreCase(name) && ConfigUtils.isProfileActive("prod")) {
+ throw new IllegalStateException(
+ "The Camel CLI connector websocket transport gives the connected tool full control of this"
+ + " application and cannot be used with the Quarkus prod profile."
+ + " Remove camel.cli.transport=websocket, or use another profile.");
+ }
+ return super.createTransport(name);
+ }
+
@Override
public void sigterm() {
if (LaunchMode.current().equals(LaunchMode.DEVELOPMENT)) {
diff --git a/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/VertxCliWebSocketClient.java b/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/VertxCliWebSocketClient.java
new file mode 100644
index 0000000000..be63336cec
--- /dev/null
+++ b/extensions-jvm/cli-connector/runtime/src/main/java/org/apache/camel/quarkus/component/cli/connector/VertxCliWebSocketClient.java
@@ -0,0 +1,198 @@
+/*
+ * 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.quarkus.component.cli.connector;
+
+import java.net.URI;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.TimeoutException;
+
+import io.quarkus.tls.TlsConfiguration;
+import io.quarkus.tls.TlsConfigurationRegistry;
+import io.quarkus.tls.runtime.config.TlsConfigUtils;
+import io.vertx.core.Future;
+import io.vertx.core.Vertx;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.core.http.UpgradeRejectedException;
+import io.vertx.core.http.WebSocket;
+import io.vertx.core.http.WebSocketClient;
+import io.vertx.core.http.WebSocketClientOptions;
+import io.vertx.core.http.WebSocketConnectOptions;
+import io.vertx.core.http.WebSocketFrame;
+import jakarta.annotation.PostConstruct;
+import jakarta.inject.Inject;
+import org.apache.camel.cli.connector.CliWebSocketClient;
+import org.apache.camel.cli.connector.CliWebSocketHandshakeException;
+import org.jboss.logging.Logger;
+
+/**
+ * The {@link CliWebSocketClient} of the Camel CLI connector WebSocket transport on Camel Quarkus, with the Vert.x
+ * WebSocket client of the application. {@code camel.cli.websocket.client=jdk} uses the JDK client instead.
+ * <p/>
+ * The handlers run on the Vert.x event loop: they only hand over to the transport, which parses and sends on its own
+ * threads.
+ */
+public class VertxCliWebSocketClient implements CliWebSocketClient {
+
+ static final String NAME = "vertx";
+ private static final Logger LOG = Logger.getLogger(VertxCliWebSocketClient.class);
+ private static final int TIMEOUT = 10000;
+ // the frames sent: servers commonly refuse frames over 64 KB (Vert.x, Quarkus), and a char takes up to 3 bytes
+ private static final int FRAME_CHARS = 16 * 1024;
+ // the messages received, in bytes: up to 3 per char
+ private static final int MAX_MESSAGE_BYTES = 3 * MAX_MESSAGE_SIZE;
+
+ @Inject
+ Vertx vertx;
+
+ @Inject
+ TlsConfigurationRegistry tlsRegistry;
+
+ @Inject
+ CamelCliConnectorRunTimeConfig config;
+
+ private TlsConfiguration tls;
+
+ @PostConstruct
+ void resolveTlsConfiguration() {
+ Optional<String> name = config.websocket().tlsConfigurationName();
+ if (name.isPresent()) {
+ tls = tlsRegistry.get(name.get()).orElseThrow(() -> new IllegalStateException(
+ "No TLS configuration named " + name.get() + " (quarkus.camel.cli.websocket.tls-configuration-name)"));
+ }
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public CompletionStage<Channel> connect(URI url, Map<String, String> headers, Listener listener) {
+ boolean ssl = "wss".equals(url.getScheme().toLowerCase(Locale.ROOT));
+ WebSocketClientOptions options = new WebSocketClientOptions()
+ .setConnectTimeout(TIMEOUT)
+ // how long the tool has to close the connection once the close frame is sent (seconds): abort() closes
+ // the client, which closes the connection like this
+ .setClosingTimeout(1)
+ // a tool can send a whole message in a single frame
+ .setMaxFrameSize(MAX_MESSAGE_BYTES)
+ .setMaxMessageSize(MAX_MESSAGE_BYTES);
+ if (ssl && tls != null) {
+ TlsConfigUtils.configure(options, tls);
+ }
+ String path = url.getRawPath() == null || url.getRawPath().isEmpty() ? "/" : url.getRawPath();
+ WebSocketConnectOptions connect = new WebSocketConnectOptions()
+ .setHost(url.getHost())
+ .setPort(url.getPort() != -1 ? url.getPort() : ssl ? 443 : 80)
+ .setSsl(ssl)
+ // the path and query as given, encoded characters included
+ .setURI(url.getRawQuery() != null ? path + "?" + url.getRawQuery() : path);
+ headers.forEach(connect::addHeader);
+
+ // a client for each connection, closed with it
+ WebSocketClient client = vertx.createWebSocketClient(options);
+ CompletableFuture<Channel> answer = new CompletableFuture<>();
+ // the handshake: not WebSocketConnectOptions.setTimeout, which is also an idle timeout that can close the
+ // connection once open
+ long timer = vertx.setTimer(TIMEOUT, id -> {
+ if (answer.completeExceptionally(new TimeoutException("WebSocket handshake timed out after " + TIMEOUT + " ms"))) {
+ client.close();
+ }
+ });
+ client.connect(connect).onComplete(ar -> {
+ vertx.cancelTimer(timer);
+ if (answer.isDone()) {
+ // timed out
+ if (ar.succeeded()) {
+ ar.result().close();
+ }
+ return;
+ }
+ if (ar.failed()) {
+ client.close();
+ answer.completeExceptionally(translate(ar.cause()));
+ return;
+ }
+ WebSocket ws = ar.result();
+ ws.textMessageHandler(listener::onText);
+ ws.pongHandler(data -> listener.onPong());
+ ws.exceptionHandler(e -> {
+ LOG.debugf(e, "Camel CLI connector WebSocket error");
+ listener.onError(e);
+ });
+ ws.closeHandler(v -> {
+ client.close();
+ // no status when the connection is lost without a close frame
+ Short code = ws.closeStatusCode();
+ LOG.debugf("Camel CLI connector WebSocket closed: %s %s", code, ws.closeReason());
+ listener.onClose(code != null ? code : 1006, ws.closeReason());
+ });
+ answer.complete(new VertxChannel(ws, client));
+ });
+ return answer;
+ }
+
+ private static Throwable translate(Throwable e) {
+ if (e instanceof UpgradeRejectedException rejected) {
+ return new CliWebSocketHandshakeException(rejected.getStatus(), rejected);
+ }
+ return e;
+ }
+
+ private record VertxChannel(WebSocket ws, WebSocketClient client) implements Channel {
+
+ @Override
+ public CompletionStage<?> sendText(String text) {
+ // in frames of FRAME_CHARS, never splitting a surrogate pair
+ Future<Void> last = null;
+ int start = 0;
+ do {
+ int end = Math.min(text.length(), start + FRAME_CHARS);
+ if (end < text.length() && Character.isHighSurrogate(text.charAt(end - 1))) {
+ end--;
+ }
+ String part = text.substring(start, end);
+ boolean fin = end == text.length();
+ last = ws.writeFrame(start == 0
+ ? WebSocketFrame.textFrame(part, fin)
+ : WebSocketFrame.continuationFrame(Buffer.buffer(part), fin));
+ start = end;
+ } while (start < text.length());
+ return last.toCompletionStage();
+ }
+
+ @Override
+ public CompletionStage<?> sendPing() {
+ return ws.writePing(Buffer.buffer()).toCompletionStage();
+ }
+
+ @Override
+ public CompletionStage<?> close(int code, String reason) {
+ return ws.close((short) code, reason).toCompletionStage();
+ }
+
+ @Override
+ public void abort() {
+ // closes the connection right away, without a close frame
+ client.close();
+ }
+ }
+}
diff --git a/integration-tests-jvm/cli-connector/pom.xml b/integration-tests-jvm/cli-connector/pom.xml
index b9e9b1e314..4f01f6ca89 100644
--- a/integration-tests-jvm/cli-connector/pom.xml
+++ b/integration-tests-jvm/cli-connector/pom.xml
@@ -36,12 +36,12 @@
<artifactId>camel-quarkus-cli-connector</artifactId>
</dependency>
<dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy</artifactId>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-management</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-management</artifactId>
+ <artifactId>camel-quarkus-direct</artifactId>
</dependency>
<!-- test dependencies -->
<dependency>
@@ -50,8 +50,13 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>io.rest-assured</groupId>
- <artifactId>rest-assured</artifactId>
+ <groupId>org.awaitility</groupId>
+ <artifactId>awaitility</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
@@ -79,6 +84,19 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-management-deployment</artifactId>
diff --git a/integration-tests-jvm/cli-connector/src/main/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorResource.java b/integration-tests-jvm/cli-connector/src/main/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorResource.java
deleted file mode 100644
index c6cdb58d7c..0000000000
--- a/integration-tests-jvm/cli-connector/src/main/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorResource.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.quarkus.component.cli.connector.it;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.apache.camel.CamelContext;
-import org.jboss.logging.Logger;
-
-@Path("/cli-connector")
-@ApplicationScoped
-public class CliConnectorResource {
-
- private static final Logger LOG = Logger.getLogger(CliConnectorResource.class);
-
- private static final String OTHER_CLI_CONNECTOR = "cli-connector";
- @Inject
- CamelContext context;
-
- @Path("/load/other/cli-connector")
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public Response loadOtherCliConnector() throws Exception {
- /* This is an autogenerated test */
- /* No way to test a Camel artifact of kind "other" */
- return Response.ok().build();
- }
-}
diff --git a/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorTest.java b/integration-tests-jvm/cli-connector/src/main/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorRoutes.java
similarity index 70%
copy from integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorTest.java
copy to integration-tests-jvm/cli-connector/src/main/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorRoutes.java
index b7b3ac7fe3..aff5d26c0f 100644
--- a/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorTest.java
+++ b/integration-tests-jvm/cli-connector/src/main/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorRoutes.java
@@ -16,19 +16,12 @@
*/
package org.apache.camel.quarkus.component.cli.connector.it;
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import org.junit.jupiter.api.Test;
+import org.apache.camel.builder.RouteBuilder;
-@QuarkusTest
-class CliConnectorTest {
-
- @Test
- public void loadOtherCliConnector() {
- /* A simple autogenerated test */
- RestAssured.get("/cli-connector/load/other/cli-connector")
- .then()
- .statusCode(200);
+public class CliConnectorRoutes extends RouteBuilder {
+ @Override
+ public void configure() {
+ from("direct:echo").routeId("echo").setBody(simple("Hello ${body}"));
+ from("direct:length").routeId("length").setBody(simple("length=${body.length()}"));
}
-
}
diff --git a/integration-tests-jvm/cli-connector/src/main/resources/application.properties b/integration-tests-jvm/cli-connector/src/main/resources/application.properties
new file mode 100644
index 0000000000..df15566cdd
--- /dev/null
+++ b/integration-tests-jvm/cli-connector/src/main/resources/application.properties
@@ -0,0 +1,25 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+# camel.cli.websocket.url and camel.cli.websocket.token are set by CliToolServer
+camel.cli.transport = websocket
+camel.cli.websocket.reconnect-delay = 100
+camel.cli.websocket.reconnect-max-delay = 500
+# trace snapshots, sent in messages of up to 128 KB
+camel.trace.enabled = true
+# the tests check what the connector logs
+quarkus.log.file.enabled = true
+quarkus.log.file.path = target/quarkus.log
diff --git a/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorTest.java b/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorTest.java
index b7b3ac7fe3..1e056bc990 100644
--- a/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorTest.java
+++ b/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliConnectorTest.java
@@ -16,19 +16,146 @@
*/
package org.apache.camel.quarkus.component.cli.connector.it;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.TimeUnit;
+
+import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
+import io.vertx.core.http.ServerWebSocket;
+import org.apache.camel.util.json.JsonObject;
import org.junit.jupiter.api.Test;
+import static org.apache.camel.quarkus.component.cli.connector.it.CliToolServer.action;
+import static org.apache.camel.quarkus.component.cli.connector.it.CliToolServer.awaitResult;
+import static org.apache.camel.quarkus.component.cli.connector.it.CliToolServer.reconnect;
+import static org.apache.camel.quarkus.component.cli.connector.it.CliToolServer.send;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+
+/**
+ * The Vert.x client, the default on Camel Quarkus.
+ */
@QuarkusTest
+@QuarkusTestResource(CliToolServer.class)
class CliConnectorTest {
+ private static final Path LOG = Paths.get("target/quarkus.log");
+
+ @Test
+ void connectsWithTheExpectedClient() throws Exception {
+ JsonObject hello = reconnect();
+
+ assertThat(hello.getString("transport")).isEqualTo("vertx");
+ assertThat(hello.getString("camelVersion")).isNotBlank();
+ // the url is used as given, encoded characters included
+ assertThat(CliToolServer.REQUEST_URIS).isNotEmpty().allSatisfy(uri -> assertThat(uri)
+ .isEqualTo(CliToolServer.REQUEST_URI));
+ }
+
+ @Test
+ void executesActions() throws Exception {
+ reconnect();
+
+ send(action("r1", "send", "endpoint", "direct:echo", "body", "World", "exchangePattern", "InOut"));
+ JsonObject result = awaitResult("r1");
+ assertThat(result.getBoolean("ok")).isTrue();
+ assertThat(resultJson(result)).contains("Hello World");
+
+ send(action("r2", "does-not-exist"));
+ result = awaitResult("r2");
+ assertThat(result.getBoolean("ok")).isFalse();
+ assertThat(result.getString("error")).isEqualTo("Unknown action: does-not-exist");
+ }
+
+ @Test
+ void exchangesLargeMessages() throws Exception {
+ reconnect();
+ // well over the 256 KB messages and the 64 KB frames that Vert.x accepts by default
+ String body = "x".repeat(4 * 1024 * 1024);
+
+ // each of them in 64 frames: more frames in total than a client fetching a fixed number of frames would read
+ for (int i = 0; i < 6; i++) {
+ send(action("r" + i, "send", "endpoint", "direct:length", "body", body, "exchangePattern", "InOut"));
+ JsonObject result = awaitResult("r" + i);
+ assertThat(result.getBoolean("ok")).isTrue();
+ assertThat(resultJson(result)).contains("length=" + body.length());
+ }
+
+ // and back: trace snapshots are sent in messages of up to 128 KB, over the 64 KB frames the tool accepts
+ String traced = "y".repeat(6000);
+ for (int i = 0; i < 40; i++) {
+ send(action("t" + i, "send", "endpoint", "direct:echo", "body", traced, "exchangePattern", "InOut"));
+ assertThat(awaitResult("t" + i).getBoolean("ok")).isTrue();
+ }
+ await().atMost(20, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertThat(CliToolServer.LARGEST_TRACE_SNAPSHOT).hasValueGreaterThan(64 * 1024));
+ }
+
+ @Test
+ void reconnectsOnceTheTokenIsAccepted() throws Exception {
+ reconnect();
+ int rejected = CliToolServer.REJECTED.get();
+ try {
+ CliToolServer.reject = true;
+ CliToolServer.SOCKETS.forEach(ServerWebSocket::close);
+
+ await().atMost(10, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertThat(CliToolServer.REJECTED).hasValueGreaterThan(rejected + 1));
+ // the client reports the HTTP status of the rejected handshake
+ await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> assertThat(Files.readString(LOG))
+ .contains("Camel CLI connector was rejected by ws://127.0.0.1:")
+ .contains("(HTTP 401): check camel.cli.websocket.token"));
+ } finally {
+ CliToolServer.reject = false;
+ }
+ // connected again once the token is accepted
+ assertThat(CliToolServer.awaitFrame(f -> "hello".equals(f.getString("type")))).isNotNull();
+ }
+
+ @Test
+ void receivesLargeActionsInASingleFrame() throws Exception {
+ reconnect();
+ // over the 64 KB frames that Vert.x accepts by default
+ String body = "x".repeat(1024 * 1024);
+
+ CliToolServer.sendInASingleFrame(
+ action("r1", "send", "endpoint", "direct:length", "body", body, "exchangePattern", "InOut"));
+ JsonObject result = awaitResult("r1");
+ assertThat(result.getBoolean("ok")).isTrue();
+ assertThat(resultJson(result)).contains("length=" + body.length());
+ }
+
+ @Test
+ void staysConnected() throws Exception {
+ reconnect();
+ int connections = CliToolServer.CONNECTIONS.get();
+
+ // longer than the connect and handshake timeouts (10 s), which must not apply once connected
+ await().during(15, TimeUnit.SECONDS).atMost(20, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertThat(CliToolServer.CONNECTIONS).hasValue(connections));
+ }
+
@Test
- public void loadOtherCliConnector() {
- /* A simple autogenerated test */
- RestAssured.get("/cli-connector/load/other/cli-connector")
- .then()
- .statusCode(200);
+ void reconnectsWhenTheToolDoesNotAnswerTheHandshake() throws Exception {
+ reconnect();
+ int unanswered = CliToolServer.UNANSWERED.get();
+ try {
+ CliToolServer.silent = true;
+ CliToolServer.SOCKETS.forEach(ServerWebSocket::close);
+
+ // the handshake times out after 10 s, and the connector tries again
+ await().atMost(40, TimeUnit.SECONDS)
+ .untilAsserted(() -> assertThat(CliToolServer.UNANSWERED).hasValueGreaterThan(unanswered + 1));
+ } finally {
+ CliToolServer.silent = false;
+ }
+ assertThat(CliToolServer.awaitFrame(f -> "hello".equals(f.getString("type")))).isNotNull();
}
+ private static String resultJson(JsonObject result) {
+ JsonObject json = result.getMap("result");
+ return json.toJson();
+ }
}
diff --git a/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliToolServer.java b/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliToolServer.java
new file mode 100644
index 0000000000..80d2705272
--- /dev/null
+++ b/integration-tests-jvm/cli-connector/src/test/java/org/apache/camel/quarkus/component/cli/connector/it/CliToolServer.java
@@ -0,0 +1,164 @@
+/*
+ * 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.quarkus.component.cli.connector.it;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
+
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import io.vertx.core.Vertx;
+import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerOptions;
+import io.vertx.core.http.ServerWebSocket;
+import io.vertx.core.http.WebSocketFrame;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
+
+import static org.awaitility.Awaitility.await;
+
+/**
+ * Plays the developer tool: a WebSocket server the Camel CLI connector of the application dials out to.
+ */
+public class CliToolServer implements QuarkusTestResourceLifecycleManager {
+
+ static final String TOKEN = "it-s3cret";
+ // a query parameter holding an encoded '&': it must reach the tool as given
+ static final String REQUEST_URI = "/v1/connect?executionId=it%261";
+ private static final int MAX_MESSAGE_SIZE = 32 * 1024 * 1024;
+
+ static final BlockingQueue<JsonObject> FRAMES = new LinkedBlockingQueue<>();
+ static final List<ServerWebSocket> SOCKETS = new CopyOnWriteArrayList<>();
+ static final List<String> REQUEST_URIS = new CopyOnWriteArrayList<>();
+ static final AtomicInteger REJECTED = new AtomicInteger();
+ static final AtomicInteger CONNECTIONS = new AtomicInteger();
+ static final AtomicInteger UNANSWERED = new AtomicInteger();
+ static volatile boolean silent;
+ static final AtomicInteger LARGEST_TRACE_SNAPSHOT = new AtomicInteger();
+ static volatile boolean reject;
+
+ private Vertx vertx;
+
+ @Override
+ public Map<String, String> start() {
+ vertx = Vertx.vertx();
+ try {
+ // frames of 64 KB at most (the Vert.x default), in both directions, as Vert.x and Quarkus servers
+ HttpServer server = vertx.createHttpServer(new HttpServerOptions()
+ .setMaxWebSocketMessageSize(MAX_MESSAGE_SIZE))
+ .webSocketHandshakeHandler(handshake -> {
+ REQUEST_URIS.add(handshake.uri());
+ if (silent) {
+ // never answers the upgrade
+ UNANSWERED.incrementAndGet();
+ return;
+ }
+ if (reject || !("Bearer " + TOKEN).equals(handshake.headers().get("Authorization"))) {
+ REJECTED.incrementAndGet();
+ handshake.reject(401);
+ } else {
+ handshake.accept();
+ }
+ })
+ .webSocketHandler(ws -> {
+ SOCKETS.add(ws);
+ CONNECTIONS.incrementAndGet();
+ ws.textMessageHandler(text -> {
+ try {
+ JsonObject frame = (JsonObject) Jsoner.deserialize(text);
+ if ("trace".equals(frame.getString("kind"))) {
+ LARGEST_TRACE_SNAPSHOT.accumulateAndGet(text.length(), Math::max);
+ }
+ FRAMES.add(frame);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ });
+ ws.closeHandler(v -> SOCKETS.remove(ws));
+ })
+ .listen(0, "127.0.0.1").toCompletionStage().toCompletableFuture().get(10, TimeUnit.SECONDS);
+ return Map.of(
+ "camel.cli.websocket.url", "ws://127.0.0.1:" + server.actualPort() + REQUEST_URI,
+ "camel.cli.websocket.token", TOKEN);
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (vertx != null) {
+ vertx.close();
+ }
+ }
+
+ /**
+ * Closes the connection, and waits for the application to connect again and say hello. The old sockets are not
+ * waited for: they are closed once the application answers the close, or after the Vert.x closing timeout.
+ */
+ static JsonObject reconnect() throws InterruptedException {
+ int connections = CONNECTIONS.get();
+ FRAMES.clear();
+ SOCKETS.forEach(ServerWebSocket::close);
+ await().atMost(20, TimeUnit.SECONDS).until(() -> CONNECTIONS.get() > connections);
+ return awaitFrame(f -> "hello".equals(f.getString("type")));
+ }
+
+ static void send(JsonObject frame) {
+ await().atMost(10, TimeUnit.SECONDS).until(() -> !SOCKETS.isEmpty());
+ // in frames of 64 KB at most, as Vert.x and Quarkus servers
+ SOCKETS.get(SOCKETS.size() - 1).writeTextMessage(frame.toJson());
+ }
+
+ static void sendInASingleFrame(JsonObject frame) {
+ await().atMost(10, TimeUnit.SECONDS).until(() -> !SOCKETS.isEmpty());
+ // as tools that never split messages, whatever the size
+ SOCKETS.get(SOCKETS.size() - 1).writeFrame(WebSocketFrame.textFrame(frame.toJson(), true));
+ }
+
+ static JsonObject action(String requestId, String name, String... keyValues) {
+ JsonObject action = new JsonObject();
+ action.put("action", name);
+ for (int i = 0; i < keyValues.length; i += 2) {
+ action.put(keyValues[i], keyValues[i + 1]);
+ }
+ return new JsonObject(Map.of("v", 1, "type", "action", "requestId", requestId, "action", action));
+ }
+
+ /**
+ * Waits for a frame matching the predicate, skipping the others (mostly snapshots).
+ */
+ static JsonObject awaitFrame(Predicate<JsonObject> predicate) throws InterruptedException {
+ long deadline = System.currentTimeMillis() + 20000;
+ while (System.currentTimeMillis() < deadline) {
+ JsonObject frame = FRAMES.poll(100, TimeUnit.MILLISECONDS);
+ if (frame != null && predicate.test(frame)) {
+ return frame;
+ }
+ }
+ throw new AssertionError("No matching frame received within 20 seconds");
+ }
+
+ static JsonObject awaitResult(String requestId) throws InterruptedException {
+ return awaitFrame(f -> "result".equals(f.getString("type")) && requestId.equals(f.getString("requestId")));
+ }
+}
(camel-quarkus) 03/04: Fixes #9231. Removed PQC native workarounds for BouncyCastle 1.86
Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
JiriOndrusek pushed a commit to branch camel-main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit 2a50b1a67cc820bc2cfe055728cf4539969835c1
Author: Jiří Ondrušek <on...@gmail.com>
AuthorDate: Tue Sep 29 16:01:46 2026 +0000
Fixes #9231. Removed PQC native workarounds for BouncyCastle 1.86
Camel main uses BouncyCastle 1.86 since apache/camel@dc7d79531a7d, so the
Picnic/FRODO/CMCE substitutions no longer compile and are not needed.
Reverts 843f97ff7ea0.
Co-Authored-By: Claude Fable 5.1 <no...@anthropic.com>
---
.../component/pqc/deployment/PqcProcessor.java | 14 ---
extensions/pqc/runtime/pom.xml | 5 -
.../component/pqc/graal/PqcSubstitutions.java | 121 ---------------------
3 files changed, 140 deletions(-)
diff --git a/extensions/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java b/extensions/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
index a92bdf60e5..425d492964 100644
--- a/extensions/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
+++ b/extensions/pqc/deployment/src/main/java/org/apache/camel/quarkus/component/pqc/deployment/PqcProcessor.java
@@ -23,10 +23,6 @@ import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageSecurityProviderBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
-import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
-import org.apache.camel.component.pqc.crypto.PQCDefaultPicnicMaterial;
-import org.apache.camel.component.pqc.crypto.kem.PQCDefaultCMCEMaterial;
-import org.apache.camel.component.pqc.crypto.kem.PQCDefaultFRODOMaterial;
import org.apache.camel.quarkus.support.bouncycastle.BouncyCastleRecorder;
import org.apache.camel.quarkus.support.bouncycastle.deployment.BouncyCastleAdditionalProviderBuildItem;
import org.jboss.jandex.IndexView;
@@ -82,14 +78,4 @@ class PqcProcessor {
return new BouncyCastleAdditionalProviderBuildItem(BouncyCastleRecorder.BOUNCYCASTLE_PCQ_PROVIDER_NAME);
}
- // TODO: Remove this - https://github.com/apache/camel-quarkus/issues/9231
- @BuildStep
- void runtimeInitializedClasses(BuildProducer<RuntimeInitializedClassBuildItem> runtimeInitializedClass) {
- runtimeInitializedClass.produce(
- new RuntimeInitializedClassBuildItem(PQCDefaultPicnicMaterial.class.getName()));
- runtimeInitializedClass.produce(
- new RuntimeInitializedClassBuildItem(PQCDefaultFRODOMaterial.class.getName()));
- runtimeInitializedClass.produce(
- new RuntimeInitializedClassBuildItem(PQCDefaultCMCEMaterial.class.getName()));
- }
}
diff --git a/extensions/pqc/runtime/pom.xml b/extensions/pqc/runtime/pom.xml
index 2839831a7b..590424a0d8 100644
--- a/extensions/pqc/runtime/pom.xml
+++ b/extensions/pqc/runtime/pom.xml
@@ -49,11 +49,6 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-support-bouncycastle</artifactId>
</dependency>
- <dependency>
- <groupId>org.graalvm.sdk</groupId>
- <artifactId>nativeimage</artifactId>
- <scope>provided</scope>
- </dependency>
</dependencies>
<build>
diff --git a/extensions/pqc/runtime/src/main/java/org/apache/camel/quarkus/component/pqc/graal/PqcSubstitutions.java b/extensions/pqc/runtime/src/main/java/org/apache/camel/quarkus/component/pqc/graal/PqcSubstitutions.java
deleted file mode 100644
index 5d080ea93c..0000000000
--- a/extensions/pqc/runtime/src/main/java/org/apache/camel/quarkus/component/pqc/graal/PqcSubstitutions.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.quarkus.component.pqc.graal;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.spec.AlgorithmParameterSpec;
-
-import com.oracle.svm.core.annotate.Substitute;
-import com.oracle.svm.core.annotate.TargetClass;
-import org.apache.camel.component.pqc.PQCKeyEncapsulationAlgorithms;
-import org.apache.camel.component.pqc.PQCParameterSpecResolver;
-import org.apache.camel.component.pqc.crypto.PQCDefaultPicnicMaterial;
-import org.apache.camel.component.pqc.crypto.kem.PQCDefaultCMCEMaterial;
-import org.apache.camel.component.pqc.crypto.kem.PQCDefaultFRODOMaterial;
-import org.apache.camel.util.SecureRandomHelper;
-import org.bouncycastle.jcajce.spec.CMCEParameterSpec;
-import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
-import org.bouncycastle.jcajce.spec.MLKEMParameterSpec;
-import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.BIKEParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.FalconParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.NTRULPRimeParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.SABERParameterSpec;
-import org.bouncycastle.pqc.jcajce.spec.SNTRUPrimeParameterSpec;
-
-/**
- * Removes references to BouncyCastle parameter specs that no longer exist in the BouncyCastle version managed by
- * Quarkus. Algorithms without a replacement spec are not supported in native mode.
- */
-// TODO: Remove this - https://github.com/apache/camel-quarkus/issues/9231
-final class PqcSubstitutions {
-}
-
-@TargetClass(PQCParameterSpecResolver.class)
-final class SubstitutePQCParameterSpecResolver {
- @Substitute
- private static AlgorithmParameterSpec doResolve(String algorithm, String parameterSpec) {
- switch (algorithm) {
- // Signature algorithms
- case "MLDSA":
- return MLDSAParameterSpec.fromName(parameterSpec);
- case "SLHDSA":
- return SLHDSAParameterSpec.fromName(parameterSpec);
- case "FALCON":
- return FalconParameterSpec.fromName(parameterSpec);
- // Key encapsulation algorithms
- case "MLKEM":
- return MLKEMParameterSpec.fromName(parameterSpec);
- case "NTRU":
- return NTRUParameterSpec.fromName(parameterSpec);
- case "NTRULPRime":
- return NTRULPRimeParameterSpec.fromName(parameterSpec);
- case "SNTRUPrime":
- return SNTRUPrimeParameterSpec.fromName(parameterSpec);
- case "BIKE":
- return BIKEParameterSpec.fromName(parameterSpec);
- case "HQC":
- return HQCParameterSpec.fromName(parameterSpec);
- case "CMCE":
- return CMCEParameterSpec.fromName(parameterSpec);
- case "SABER":
- return SABERParameterSpec.fromName(parameterSpec);
- case "DILITHIUM":
- case "SPHINCSPLUS":
- case "PICNIC":
- case "KYBER":
- case "FRODO":
- throw new UnsupportedOperationException(
- "The parameterSpec option is not supported for algorithm " + algorithm + " in native mode");
- default:
- throw new IllegalStateException("Unsupported algorithm: " + algorithm);
- }
- }
-}
-
-@TargetClass(PQCDefaultPicnicMaterial.class)
-final class SubstitutePQCDefaultPicnicMaterial {
- @Substitute
- protected static KeyPairGenerator prepareKeyPair() {
- throw new UnsupportedOperationException("The PICNIC algorithm is not supported in native mode");
- }
-}
-
-@TargetClass(PQCDefaultFRODOMaterial.class)
-final class SubstitutePQCDefaultFRODOMaterial {
- @Substitute
- protected static KeyPairGenerator prepareKeyPair() {
- throw new UnsupportedOperationException("The FRODO algorithm is not supported in native mode");
- }
-}
-
-@TargetClass(PQCDefaultCMCEMaterial.class)
-final class SubstitutePQCDefaultCMCEMaterial {
- @Substitute
- protected static KeyPairGenerator prepareKeyPair()
- throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
- KeyPairGenerator kpg = KeyPairGenerator.getInstance(PQCKeyEncapsulationAlgorithms.CMCE.getAlgorithm(),
- PQCKeyEncapsulationAlgorithms.CMCE.getBcProvider());
- kpg.initialize(CMCEParameterSpec.mceliece8192128f, SecureRandomHelper.getSecureRandom());
- return kpg;
- }
-}