This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new c09ae47cafea CAMEL-24519: camel-ibm-watsonx-ai - relabel the ModelId
output header and synchronize the lazy service getters (CAMEL-24520) (#25787)
c09ae47cafea is described below
commit c09ae47cafea8a3d13b64e52e18daf34f5ae952c
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu Aug 27 11:19:48 2026 +0200
CAMEL-24519: camel-ibm-watsonx-ai - relabel the ModelId output header and
synchronize the lazy service getters (CAMEL-24520) (#25787)
* CAMEL-24519: camel-ibm-watsonx-ai - relabel the ModelId header as an
output
The CamelIbmWatsonxAiModelId header was documented as "The model ID to use",
implying a per-exchange input. The model is fixed at service-creation time
and
the header is only written to the response to report the model used, so the
metadata is relabelled accordingly (label producer).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Signed-off-by: Andrea Cosentino <[email protected]>
* CAMEL-24520: camel-ibm-watsonx-ai - make the lazy service getters
thread-safe
WatsonxAiEndpoint builds each watsonx.ai service lazily in its getter; the
lazy
creation is intentional but was not synchronized, so concurrent first-use
could
build (and leak) a duplicate client. Make the getters synchronized while
keeping
the lazy creation.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Signed-off-by: Andrea Cosentino <[email protected]>
---------
Signed-off-by: Andrea Cosentino <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
---
.../camel/catalog/components/ibm-watsonx-ai.json | 2 +-
.../component/ibm/watsonx/ai/ibm-watsonx-ai.json | 2 +-
.../ibm/watsonx/ai/WatsonxAiConstants.java | 3 ++-
.../ibm/watsonx/ai/WatsonxAiEndpoint.java | 24 +++++++++++-----------
.../dsl/WatsonxAiEndpointBuilderFactory.java | 2 +-
5 files changed, 17 insertions(+), 16 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ibm-watsonx-ai.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ibm-watsonx-ai.json
index 1d579d6fa8a6..6d6f657f0b79 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ibm-watsonx-ai.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/ibm-watsonx-ai.json
@@ -65,7 +65,7 @@
"CamelIBMWatsonxAiInput": { "index": 1, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The input text\/prompt for generation", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#INPUT" },
"CamelIBMWatsonxAiInputs": { "index": 2, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType":
"java.util.List<String>", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The list of inputs for
batch operations", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#INPUTS" },
"CamelIBMWatsonxAiGeneratedText": { "index": 3, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The generated text output",
"constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#GENERATED_TEXT" },
- "CamelIBMWatsonxAiModelId": { "index": 4, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The model ID to use", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#MODEL_ID" },
+ "CamelIBMWatsonxAiModelId": { "index": 4, "kind": "header", "displayName":
"", "group": "producer", "label": "producer", "required": false, "javaType":
"String", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "The model ID used for the request, reported on
the response", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#MODEL_ID" },
"CamelIBMWatsonxAiDeploymentId": { "index": 5, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The deployment ID to use",
"constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#DEPLOYMENT_ID" },
"CamelIBMWatsonxAiSpaceId": { "index": 6, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The space ID for deployment operations", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#SPACE_ID" },
"CamelIBMWatsonxAiDeploymentName": { "index": 7, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The deployment name", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#DEPLOYMENT_NAME"
},
diff --git
a/components/camel-ibm/camel-ibm-watsonx-ai/src/generated/resources/META-INF/org/apache/camel/component/ibm/watsonx/ai/ibm-watsonx-ai.json
b/components/camel-ibm/camel-ibm-watsonx-ai/src/generated/resources/META-INF/org/apache/camel/component/ibm/watsonx/ai/ibm-watsonx-ai.json
index 1d579d6fa8a6..6d6f657f0b79 100644
---
a/components/camel-ibm/camel-ibm-watsonx-ai/src/generated/resources/META-INF/org/apache/camel/component/ibm/watsonx/ai/ibm-watsonx-ai.json
+++
b/components/camel-ibm/camel-ibm-watsonx-ai/src/generated/resources/META-INF/org/apache/camel/component/ibm/watsonx/ai/ibm-watsonx-ai.json
@@ -65,7 +65,7 @@
"CamelIBMWatsonxAiInput": { "index": 1, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The input text\/prompt for generation", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#INPUT" },
"CamelIBMWatsonxAiInputs": { "index": 2, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType":
"java.util.List<String>", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The list of inputs for
batch operations", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#INPUTS" },
"CamelIBMWatsonxAiGeneratedText": { "index": 3, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The generated text output",
"constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#GENERATED_TEXT" },
- "CamelIBMWatsonxAiModelId": { "index": 4, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The model ID to use", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#MODEL_ID" },
+ "CamelIBMWatsonxAiModelId": { "index": 4, "kind": "header", "displayName":
"", "group": "producer", "label": "producer", "required": false, "javaType":
"String", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "The model ID used for the request, reported on
the response", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#MODEL_ID" },
"CamelIBMWatsonxAiDeploymentId": { "index": 5, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The deployment ID to use",
"constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#DEPLOYMENT_ID" },
"CamelIBMWatsonxAiSpaceId": { "index": 6, "kind": "header", "displayName":
"", "group": "producer", "label": "", "required": false, "javaType": "String",
"deprecated": false, "deprecationNote": "", "autowired": false, "secret":
false, "description": "The space ID for deployment operations", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#SPACE_ID" },
"CamelIBMWatsonxAiDeploymentName": { "index": 7, "kind": "header",
"displayName": "", "group": "producer", "label": "", "required": false,
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired":
false, "secret": false, "description": "The deployment name", "constantName":
"org.apache.camel.component.ibm.watsonx.ai.WatsonxAiConstants#DEPLOYMENT_NAME"
},
diff --git
a/components/camel-ibm/camel-ibm-watsonx-ai/src/main/java/org/apache/camel/component/ibm/watsonx/ai/WatsonxAiConstants.java
b/components/camel-ibm/camel-ibm-watsonx-ai/src/main/java/org/apache/camel/component/ibm/watsonx/ai/WatsonxAiConstants.java
index 9b9a0278418c..dd02ea0e7d52 100644
---
a/components/camel-ibm/camel-ibm-watsonx-ai/src/main/java/org/apache/camel/component/ibm/watsonx/ai/WatsonxAiConstants.java
+++
b/components/camel-ibm/camel-ibm-watsonx-ai/src/main/java/org/apache/camel/component/ibm/watsonx/ai/WatsonxAiConstants.java
@@ -40,7 +40,8 @@ public interface WatsonxAiConstants {
String GENERATED_TEXT = HEADER_PREFIX + "GeneratedText";
// Model/Deployment
- @Metadata(description = "The model ID to use", javaType = "String")
+ @Metadata(label = "producer", description = "The model ID used for the
request, reported on the response",
+ javaType = "String")
String MODEL_ID = HEADER_PREFIX + "ModelId";
@Metadata(description = "The deployment ID to use", javaType = "String")
diff --git
a/components/camel-ibm/camel-ibm-watsonx-ai/src/main/java/org/apache/camel/component/ibm/watsonx/ai/WatsonxAiEndpoint.java
b/components/camel-ibm/camel-ibm-watsonx-ai/src/main/java/org/apache/camel/component/ibm/watsonx/ai/WatsonxAiEndpoint.java
index 9e7dd64eb981..42f8dc8327af 100644
---
a/components/camel-ibm/camel-ibm-watsonx-ai/src/main/java/org/apache/camel/component/ibm/watsonx/ai/WatsonxAiEndpoint.java
+++
b/components/camel-ibm/camel-ibm-watsonx-ai/src/main/java/org/apache/camel/component/ibm/watsonx/ai/WatsonxAiEndpoint.java
@@ -139,7 +139,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the TextGenerationService instance.
*/
- public TextGenerationService getTextGenerationService() {
+ public synchronized TextGenerationService getTextGenerationService() {
if (textGenerationService == null) {
textGenerationService =
WatsonxAiServiceFactory.createTextGenerationService(configuration);
}
@@ -149,7 +149,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the ChatService instance.
*/
- public ChatService getChatService() {
+ public synchronized ChatService getChatService() {
if (chatService == null) {
chatService =
WatsonxAiServiceFactory.createChatService(configuration);
}
@@ -159,7 +159,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the EmbeddingService instance.
*/
- public EmbeddingService getEmbeddingService() {
+ public synchronized EmbeddingService getEmbeddingService() {
if (embeddingService == null) {
embeddingService =
WatsonxAiServiceFactory.createEmbeddingService(configuration);
}
@@ -169,7 +169,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the RerankService instance.
*/
- public RerankService getRerankService() {
+ public synchronized RerankService getRerankService() {
if (rerankService == null) {
rerankService =
WatsonxAiServiceFactory.createRerankService(configuration);
}
@@ -179,7 +179,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the TokenizationService instance.
*/
- public TokenizationService getTokenizationService() {
+ public synchronized TokenizationService getTokenizationService() {
if (tokenizationService == null) {
tokenizationService =
WatsonxAiServiceFactory.createTokenizationService(configuration);
}
@@ -189,7 +189,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the DetectionService instance.
*/
- public DetectionService getDetectionService() {
+ public synchronized DetectionService getDetectionService() {
if (detectionService == null) {
detectionService =
WatsonxAiServiceFactory.createDetectionService(configuration);
}
@@ -199,7 +199,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the TextExtractionService instance.
*/
- public TextExtractionService getTextExtractionService() {
+ public synchronized TextExtractionService getTextExtractionService() {
if (textExtractionService == null) {
textExtractionService =
WatsonxAiServiceFactory.createTextExtractionService(configuration);
}
@@ -209,7 +209,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the TextClassificationService instance.
*/
- public TextClassificationService getTextClassificationService() {
+ public synchronized TextClassificationService
getTextClassificationService() {
if (textClassificationService == null) {
textClassificationService =
WatsonxAiServiceFactory.createTextClassificationService(configuration);
}
@@ -219,7 +219,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the TimeSeriesService instance.
*/
- public TimeSeriesService getTimeSeriesService() {
+ public synchronized TimeSeriesService getTimeSeriesService() {
if (timeSeriesService == null) {
timeSeriesService =
WatsonxAiServiceFactory.createTimeSeriesService(configuration);
}
@@ -229,7 +229,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the FoundationModelService instance.
*/
- public FoundationModelService getFoundationModelService() {
+ public synchronized FoundationModelService getFoundationModelService() {
if (foundationModelService == null) {
foundationModelService =
WatsonxAiServiceFactory.createFoundationModelService(configuration);
}
@@ -239,7 +239,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the DeploymentService instance.
*/
- public DeploymentService getDeploymentService() {
+ public synchronized DeploymentService getDeploymentService() {
if (deploymentService == null) {
deploymentService =
WatsonxAiServiceFactory.createDeploymentService(configuration);
}
@@ -249,7 +249,7 @@ public class WatsonxAiEndpoint extends DefaultEndpoint
implements EndpointServic
/**
* Gets or creates the ToolService instance.
*/
- public ToolService getToolService() {
+ public synchronized ToolService getToolService() {
if (toolService == null) {
toolService =
WatsonxAiServiceFactory.createToolService(configuration);
}
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/WatsonxAiEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/WatsonxAiEndpointBuilderFactory.java
index 466ebce0ce75..81895346e3de 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/WatsonxAiEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/WatsonxAiEndpointBuilderFactory.java
@@ -970,7 +970,7 @@ public interface WatsonxAiEndpointBuilderFactory {
return "CamelIBMWatsonxAiGeneratedText";
}
/**
- * The model ID to use.
+ * The model ID used for the request, reported on the response.
*
* The option is a: {@code String} type.
*