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.
          * 

Reply via email to