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

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


The following commit(s) were added to refs/heads/main by this push:
     new 892ba4e18f0e CAMEL-26241: camel-kubernetes - openshift producers use 
the namespace header and option in every operation (#29101)
892ba4e18f0e is described below

commit 892ba4e18f0eac9416eacd1bc9fbc12c62dc3522
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Nov 4 20:49:34 2026 +0100

    CAMEL-26241: camel-kubernetes - openshift producers use the namespace 
header and option in every operation (#29101)
    
    - CAMEL-26241: camel-kubernetes - openshift producers use the namespace 
header and option in every operation
    - CAMEL-26241: camel-kubernetes - openshift-deploymentconfigs create/update 
without a name says a Deployment Config name is required
    - CAMEL-26241: camel-kubernetes - openshift producers use 
KubernetesHelper.extractNamespace, scaleDeploymentConfig returns the spec 
replicas
    - CAMEL-26241: camel-kubernetes - test getBuildConfig with the namespace 
option
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../components/openshift-build-configs.json        |   2 +-
 .../camel/catalog/components/openshift-builds.json |   2 +-
 .../components/openshift-deploymentconfigs.json    |   4 +-
 .../docs/openshift-build-configs-component.adoc    |   6 +-
 .../catalog/docs/openshift-builds-component.adoc   |   4 +
 .../openshift-deploymentconfigs-component.adoc     |   7 +-
 .../build_configs/openshift-build-configs.json     |   2 +-
 .../openshift/builds/openshift-builds.json         |   2 +-
 .../openshift-deploymentconfigs.json               |   4 +-
 .../docs/openshift-build-configs-component.adoc    |   6 +-
 .../src/main/docs/openshift-builds-component.adoc  |   4 +
 .../openshift-deploymentconfigs-component.adoc     |   7 +-
 .../OpenshiftBuildConfigsEndpoint.java             |   6 +-
 .../OpenshiftBuildConfigsProducer.java             |  19 +-
 .../openshift/builds/OpenshiftBuildsEndpoint.java  |   6 +-
 .../openshift/builds/OpenshiftBuildsProducer.java  |  17 +-
 .../OpenshiftDeploymentConfigsEndpoint.java        |  10 +-
 .../OpenshiftDeploymentConfigsProducer.java        |  35 ++-
 .../producer/OpenshiftProducersNamespaceTest.java  | 298 +++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |  12 +
 20 files changed, 414 insertions(+), 39 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-build-configs.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-build-configs.json
index 1e122503e63b..76c8fcbc503c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-build-configs.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-build-configs.json
@@ -35,7 +35,7 @@
     "CamelKubernetesBuildConfigName": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Openshift Config Build name", 
"constantName": 
"org.apache.camel.component.kubernetes.KubernetesConstants#KUBERNETES_BUILD_CONFIG_NAME"
 }
   },
   "bodyTypes": {
-    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName, 
the name in CamelKubernetesBuildConfigName and the labels in 
CamelKubernetesBuildConfigsLabels. listBuildConfigs does not read the namespace 
header: it lists the build configs of all namespaces" },
+    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName 
(else the namespace option), the name in CamelKubernetesBuildConfigName and the 
labels in CamelKubernetesBuildConfigsLabels. Without a namespace the list 
operations list the build configs of all namespaces" },
     "producerOut": { "carriers": [ "list", "pojo", "null" ], "byOption": [ { 
"option": "operation", "value": "listBuildConfigs", "carriers": [ "list" ], 
"javaType": "java.util.List<io.fabric8.openshift.api.model.BuildConfig>" }, { 
"option": "operation", "value": "listBuildConfigsByLabels", "carriers": [ 
"list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.BuildConfig>" }, { "option": 
"operation", "value": "getBuildConfig", "carriers": [ "pojo", "null" ], 
"javaType": "io.f [...]
   },
   "properties": {
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-builds.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-builds.json
index 04b0baf9f398..faee0219feb4 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-builds.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-builds.json
@@ -35,7 +35,7 @@
     "CamelKubernetesBuildName": { "index": 3, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The OpenShift build name", "constantName": 
"org.apache.camel.component.kubernetes.KubernetesConstants#KUBERNETES_BUILD_NAME"
 }
   },
   "bodyTypes": {
-    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName, 
the name in CamelKubernetesBuildName and the labels in 
CamelKubernetesBuildsLabels. listBuilds does not read the namespace header: it 
lists the builds of all namespaces" },
+    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName 
(else the namespace option), the name in CamelKubernetesBuildName and the 
labels in CamelKubernetesBuildsLabels. Without a namespace the list operations 
list the builds of all namespaces" },
     "producerOut": { "carriers": [ "list", "pojo", "null" ], "byOption": [ { 
"option": "operation", "value": "listBuilds", "carriers": [ "list" ], 
"javaType": "java.util.List<io.fabric8.openshift.api.model.Build>" }, { 
"option": "operation", "value": "listBuildsByLabels", "carriers": [ "list" ], 
"javaType": "java.util.List<io.fabric8.openshift.api.model.Build>" }, { 
"option": "operation", "value": "getBuild", "carriers": [ "pojo", "null" ], 
"javaType": "io.fabric8.openshift.api.model.Bui [...]
   },
   "properties": {
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-deploymentconfigs.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-deploymentconfigs.json
index 3867981619cf..02df74e35afd 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-deploymentconfigs.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/openshift-deploymentconfigs.json
@@ -42,8 +42,8 @@
   },
   "bodyTypes": {
     "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"io.fabric8.openshift.api.model.DeploymentConfig", "description": "The 
DeploymentConfig that changed, one message per watch event, with the action 
(ADDED, MODIFIED, DELETED) in the CamelKubernetesEventAction header" },
-    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName, 
the name in CamelKubernetesDeploymentName, the labels in 
CamelKubernetesDeploymentsLabels, the DeploymentConfigSpec in 
CamelKubernetesDeploymentConfigSpec and the replicas in 
CamelKubernetesDeploymentReplicas. The list and get operations do not read the 
namespace  [...]
-    "producerOut": { "carriers": [ "list", "pojo", "null", "value" ], 
"byOption": [ { "option": "operation", "value": "listDeploymentConfigs", 
"carriers": [ "list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.DeploymentConfig>" }, { 
"option": "operation", "value": "listDeploymentConfigsByLabels", "carriers": [ 
"list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.DeploymentConfig>" }, { 
"option": "operation", "value": "getDeploymentConfig", "carriers": [ " [...]
+    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName 
(else the namespace option), the name in CamelKubernetesDeploymentName, the 
labels in CamelKubernetesDeploymentsLabels, the DeploymentConfigSpec in 
CamelKubernetesDeploymentConfigSpec and the replicas in 
CamelKubernetesDeploymentReplicas. Without a namespace the li [...]
+    "producerOut": { "carriers": [ "list", "pojo", "null", "value" ], 
"byOption": [ { "option": "operation", "value": "listDeploymentConfigs", 
"carriers": [ "list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.DeploymentConfig>" }, { 
"option": "operation", "value": "listDeploymentConfigsByLabels", "carriers": [ 
"list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.DeploymentConfig>" }, { 
"option": "operation", "value": "getDeploymentConfig", "carriers": [ " [...]
   },
   "properties": {
     "masterUrl": { "index": 0, "kind": "path", "displayName": "Master Url", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.kubernetes.KubernetesConfiguration", 
"configurationField": "configuration", "description": "URL to a remote 
Kubernetes API server. This should only be used when your Camel application i 
[...]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-build-configs-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-build-configs-component.adoc
index acaf39923331..9ed97eb8db8b 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-build-configs-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-build-configs-component.adoc
@@ -33,6 +33,10 @@ include::partial$component-endpoint-headers.adoc[]
 - `listBuildConfigsByLabels`
 - `getBuildConfig`
 
+The operations use the namespace of the `CamelKubernetesNamespaceName` header, 
or else of the `namespace` option.
+Without a namespace, `listBuildConfigs` and `listBuildConfigsByLabels` list 
the build configs of all namespaces;
+`getBuildConfig` requires one. `listBuildConfigsByLabels` requires the 
`CamelKubernetesBuildConfigsLabels` header.
+
 == Examples
 
 === Openshift Build Configs Producer Examples
@@ -81,7 +85,7 @@ YAML::
 
 This operation returns a list of builds from your Openshift cluster
 
-- `listBuildsByLabels`: this operation lists the build configs by labels on an 
Openshift cluster
+- `listBuildConfigsByLabels`: this operation lists the build configs by labels 
on an Openshift cluster
 
 ._Java-only: sets a Map header for label selection_
 [source,java]
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-builds-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-builds-component.adoc
index 32103e013102..af8890ba729b 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-builds-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-builds-component.adoc
@@ -33,6 +33,10 @@ include::partial$component-endpoint-headers.adoc[]
 - `listBuildsByLabels`
 - `getBuild`
 
+The operations use the namespace of the `CamelKubernetesNamespaceName` header, 
or else of the `namespace` option.
+Without a namespace, `listBuilds` and `listBuildsByLabels` list the builds of 
all namespaces; `getBuild` requires one.
+`listBuildsByLabels` requires the `CamelKubernetesBuildsLabels` header.
+
 == Examples
 
 === Openshift Builds Producer Examples
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-deploymentconfigs-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-deploymentconfigs-component.adoc
index 1e7848766b68..bf7b2310e67e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-deploymentconfigs-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/openshift-deploymentconfigs-component.adoc
@@ -28,13 +28,18 @@ include::partial$component-endpoint-headers.adoc[]
 === Supported producer operation
 
 - `listDeploymentConfigs`
-- `listDeploymentsConfigsByLabels`
+- `listDeploymentConfigsByLabels`
 - `getDeploymentConfig`
 - `createDeploymentConfig`
 - `updateDeploymentConfig`
 - `deleteDeploymentConfig`
 - `scaleDeploymentConfig`
 
+The operations use the namespace of the `CamelKubernetesNamespaceName` header, 
or else of the `namespace` option.
+Without a namespace, `listDeploymentConfigs`, `listDeploymentConfigsByLabels` 
and `getDeploymentConfig` use the
+namespace of the Kubernetes client; the other operations require one. 
`listDeploymentConfigsByLabels` requires the
+`CamelKubernetesDeploymentsLabels` header. `scaleDeploymentConfig` returns the 
replicas in the spec of the scaled deployment config.
+
 == Examples
 
 === Openshift Deployment Configs Producer Examples
diff --git 
a/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/build_configs/openshift-build-configs.json
 
b/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/build_configs/openshift-build-configs.json
index 1e122503e63b..76c8fcbc503c 100644
--- 
a/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/build_configs/openshift-build-configs.json
+++ 
b/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/build_configs/openshift-build-configs.json
@@ -35,7 +35,7 @@
     "CamelKubernetesBuildConfigName": { "index": 3, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Openshift Config Build name", 
"constantName": 
"org.apache.camel.component.kubernetes.KubernetesConstants#KUBERNETES_BUILD_CONFIG_NAME"
 }
   },
   "bodyTypes": {
-    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName, 
the name in CamelKubernetesBuildConfigName and the labels in 
CamelKubernetesBuildConfigsLabels. listBuildConfigs does not read the namespace 
header: it lists the build configs of all namespaces" },
+    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName 
(else the namespace option), the name in CamelKubernetesBuildConfigName and the 
labels in CamelKubernetesBuildConfigsLabels. Without a namespace the list 
operations list the build configs of all namespaces" },
     "producerOut": { "carriers": [ "list", "pojo", "null" ], "byOption": [ { 
"option": "operation", "value": "listBuildConfigs", "carriers": [ "list" ], 
"javaType": "java.util.List<io.fabric8.openshift.api.model.BuildConfig>" }, { 
"option": "operation", "value": "listBuildConfigsByLabels", "carriers": [ 
"list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.BuildConfig>" }, { "option": 
"operation", "value": "getBuildConfig", "carriers": [ "pojo", "null" ], 
"javaType": "io.f [...]
   },
   "properties": {
diff --git 
a/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/builds/openshift-builds.json
 
b/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/builds/openshift-builds.json
index 04b0baf9f398..faee0219feb4 100644
--- 
a/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/builds/openshift-builds.json
+++ 
b/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/builds/openshift-builds.json
@@ -35,7 +35,7 @@
     "CamelKubernetesBuildName": { "index": 3, "kind": "header", "displayName": 
"", "group": "producer", "label": "producer", "required": false, "javaType": 
"String", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The OpenShift build name", "constantName": 
"org.apache.camel.component.kubernetes.KubernetesConstants#KUBERNETES_BUILD_NAME"
 }
   },
   "bodyTypes": {
-    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName, 
the name in CamelKubernetesBuildName and the labels in 
CamelKubernetesBuildsLabels. listBuilds does not read the namespace header: it 
lists the builds of all namespaces" },
+    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName 
(else the namespace option), the name in CamelKubernetesBuildName and the 
labels in CamelKubernetesBuildsLabels. Without a namespace the list operations 
list the builds of all namespaces" },
     "producerOut": { "carriers": [ "list", "pojo", "null" ], "byOption": [ { 
"option": "operation", "value": "listBuilds", "carriers": [ "list" ], 
"javaType": "java.util.List<io.fabric8.openshift.api.model.Build>" }, { 
"option": "operation", "value": "listBuildsByLabels", "carriers": [ "list" ], 
"javaType": "java.util.List<io.fabric8.openshift.api.model.Build>" }, { 
"option": "operation", "value": "getBuild", "carriers": [ "pojo", "null" ], 
"javaType": "io.fabric8.openshift.api.model.Bui [...]
   },
   "properties": {
diff --git 
a/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/deploymentconfigs/openshift-deploymentconfigs.json
 
b/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/deploymentconfigs/openshift-deploymentconfigs.json
index 3867981619cf..02df74e35afd 100644
--- 
a/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/deploymentconfigs/openshift-deploymentconfigs.json
+++ 
b/components/camel-kubernetes/src/generated/resources/META-INF/org/apache/camel/component/openshift/deploymentconfigs/openshift-deploymentconfigs.json
@@ -42,8 +42,8 @@
   },
   "bodyTypes": {
     "consumerOut": { "carriers": [ "pojo" ], "javaType": 
"io.fabric8.openshift.api.model.DeploymentConfig", "description": "The 
DeploymentConfig that changed, one message per watch event, with the action 
(ADDED, MODIFIED, DELETED) in the CamelKubernetesEventAction header" },
-    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName, 
the name in CamelKubernetesDeploymentName, the labels in 
CamelKubernetesDeploymentsLabels, the DeploymentConfigSpec in 
CamelKubernetesDeploymentConfigSpec and the replicas in 
CamelKubernetesDeploymentReplicas. The list and get operations do not read the 
namespace  [...]
-    "producerOut": { "carriers": [ "list", "pojo", "null", "value" ], 
"byOption": [ { "option": "operation", "value": "listDeploymentConfigs", 
"carriers": [ "list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.DeploymentConfig>" }, { 
"option": "operation", "value": "listDeploymentConfigsByLabels", "carriers": [ 
"list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.DeploymentConfig>" }, { 
"option": "operation", "value": "getDeploymentConfig", "carriers": [ " [...]
+    "producerIn": { "carriers": [ "any" ], "description": "Not used: the 
operation (the operation option, or else the CamelKubernetesOperation header) 
takes its input from headers: the namespace in CamelKubernetesNamespaceName 
(else the namespace option), the name in CamelKubernetesDeploymentName, the 
labels in CamelKubernetesDeploymentsLabels, the DeploymentConfigSpec in 
CamelKubernetesDeploymentConfigSpec and the replicas in 
CamelKubernetesDeploymentReplicas. Without a namespace the li [...]
+    "producerOut": { "carriers": [ "list", "pojo", "null", "value" ], 
"byOption": [ { "option": "operation", "value": "listDeploymentConfigs", 
"carriers": [ "list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.DeploymentConfig>" }, { 
"option": "operation", "value": "listDeploymentConfigsByLabels", "carriers": [ 
"list" ], "javaType": 
"java.util.List<io.fabric8.openshift.api.model.DeploymentConfig>" }, { 
"option": "operation", "value": "getDeploymentConfig", "carriers": [ " [...]
   },
   "properties": {
     "masterUrl": { "index": 0, "kind": "path", "displayName": "Master Url", 
"group": "common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.kubernetes.KubernetesConfiguration", 
"configurationField": "configuration", "description": "URL to a remote 
Kubernetes API server. This should only be used when your Camel application i 
[...]
diff --git 
a/components/camel-kubernetes/src/main/docs/openshift-build-configs-component.adoc
 
b/components/camel-kubernetes/src/main/docs/openshift-build-configs-component.adoc
index acaf39923331..9ed97eb8db8b 100644
--- 
a/components/camel-kubernetes/src/main/docs/openshift-build-configs-component.adoc
+++ 
b/components/camel-kubernetes/src/main/docs/openshift-build-configs-component.adoc
@@ -33,6 +33,10 @@ include::partial$component-endpoint-headers.adoc[]
 - `listBuildConfigsByLabels`
 - `getBuildConfig`
 
+The operations use the namespace of the `CamelKubernetesNamespaceName` header, 
or else of the `namespace` option.
+Without a namespace, `listBuildConfigs` and `listBuildConfigsByLabels` list 
the build configs of all namespaces;
+`getBuildConfig` requires one. `listBuildConfigsByLabels` requires the 
`CamelKubernetesBuildConfigsLabels` header.
+
 == Examples
 
 === Openshift Build Configs Producer Examples
@@ -81,7 +85,7 @@ YAML::
 
 This operation returns a list of builds from your Openshift cluster
 
-- `listBuildsByLabels`: this operation lists the build configs by labels on an 
Openshift cluster
+- `listBuildConfigsByLabels`: this operation lists the build configs by labels 
on an Openshift cluster
 
 ._Java-only: sets a Map header for label selection_
 [source,java]
diff --git 
a/components/camel-kubernetes/src/main/docs/openshift-builds-component.adoc 
b/components/camel-kubernetes/src/main/docs/openshift-builds-component.adoc
index 32103e013102..af8890ba729b 100644
--- a/components/camel-kubernetes/src/main/docs/openshift-builds-component.adoc
+++ b/components/camel-kubernetes/src/main/docs/openshift-builds-component.adoc
@@ -33,6 +33,10 @@ include::partial$component-endpoint-headers.adoc[]
 - `listBuildsByLabels`
 - `getBuild`
 
+The operations use the namespace of the `CamelKubernetesNamespaceName` header, 
or else of the `namespace` option.
+Without a namespace, `listBuilds` and `listBuildsByLabels` list the builds of 
all namespaces; `getBuild` requires one.
+`listBuildsByLabels` requires the `CamelKubernetesBuildsLabels` header.
+
 == Examples
 
 === Openshift Builds Producer Examples
diff --git 
a/components/camel-kubernetes/src/main/docs/openshift-deploymentconfigs-component.adoc
 
b/components/camel-kubernetes/src/main/docs/openshift-deploymentconfigs-component.adoc
index 1e7848766b68..bf7b2310e67e 100644
--- 
a/components/camel-kubernetes/src/main/docs/openshift-deploymentconfigs-component.adoc
+++ 
b/components/camel-kubernetes/src/main/docs/openshift-deploymentconfigs-component.adoc
@@ -28,13 +28,18 @@ include::partial$component-endpoint-headers.adoc[]
 === Supported producer operation
 
 - `listDeploymentConfigs`
-- `listDeploymentsConfigsByLabels`
+- `listDeploymentConfigsByLabels`
 - `getDeploymentConfig`
 - `createDeploymentConfig`
 - `updateDeploymentConfig`
 - `deleteDeploymentConfig`
 - `scaleDeploymentConfig`
 
+The operations use the namespace of the `CamelKubernetesNamespaceName` header, 
or else of the `namespace` option.
+Without a namespace, `listDeploymentConfigs`, `listDeploymentConfigsByLabels` 
and `getDeploymentConfig` use the
+namespace of the Kubernetes client; the other operations require one. 
`listDeploymentConfigsByLabels` requires the
+`CamelKubernetesDeploymentsLabels` header. `scaleDeploymentConfig` returns the 
replicas in the spec of the scaled deployment config.
+
 == Examples
 
 === Openshift Deployment Configs Producer Examples
diff --git 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/build_configs/OpenshiftBuildConfigsEndpoint.java
 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/build_configs/OpenshiftBuildConfigsEndpoint.java
index 7be032e4843f..3335981084d3 100644
--- 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/build_configs/OpenshiftBuildConfigsEndpoint.java
+++ 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/build_configs/OpenshiftBuildConfigsEndpoint.java
@@ -40,10 +40,10 @@ import static 
org.apache.camel.component.kubernetes.KubernetesConstants.SCHEME_B
 @BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
                                   description = "Not used: the operation (the 
operation option, or else the"
                                                 + " CamelKubernetesOperation 
header) takes its input from headers: the"
-                                                + " namespace in 
CamelKubernetesNamespaceName, the name in"
+                                                + " namespace in 
CamelKubernetesNamespaceName (else the namespace option), the name in"
                                                 + " 
CamelKubernetesBuildConfigName and the labels in"
-                                                + " 
CamelKubernetesBuildConfigsLabels. listBuildConfigs does not read the"
-                                                + " namespace header: it lists 
the build configs of all namespaces"),
+                                                + " 
CamelKubernetesBuildConfigsLabels. Without a namespace the list operations"
+                                                + " list the build configs of 
all namespaces"),
            producerOut = @BodyType(value = { Carrier.LIST, Carrier.POJO, 
Carrier.NULL },
                                    byOption = {
                                            @BodyType.When(option = 
"operation", value = "listBuildConfigs",
diff --git 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/build_configs/OpenshiftBuildConfigsProducer.java
 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/build_configs/OpenshiftBuildConfigsProducer.java
index 6057993c6454..6ef751c5a314 100644
--- 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/build_configs/OpenshiftBuildConfigsProducer.java
+++ 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/build_configs/OpenshiftBuildConfigsProducer.java
@@ -70,14 +70,25 @@ public class OpenshiftBuildConfigsProducer extends 
DefaultProducer {
     }
 
     protected void doList(Exchange exchange) {
-        BuildConfigList buildConfigsList
-                = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).buildConfigs().inAnyNamespace().list();
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
+        BuildConfigList buildConfigsList;
+        if (!ObjectHelper.isEmpty(namespaceName)) {
+            buildConfigsList = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).buildConfigs()
+                    .inNamespace(namespaceName).list();
+        } else {
+            buildConfigsList = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).buildConfigs()
+                    .inAnyNamespace().list();
+        }
         exchange.getMessage().setBody(buildConfigsList.getItems());
     }
 
     protected void doListBuildConfigsByLabels(Exchange exchange) {
         Map<String, String> labels = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_BUILD_CONFIGS_LABELS, 
Map.class);
-        String namespaceName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, 
String.class);
+        if (ObjectHelper.isEmpty(labels)) {
+            LOG.error("Listing Build Configs by labels requires specifying 
labels");
+            throw new IllegalArgumentException("Listing Build Configs by 
labels requires specifying labels");
+        }
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
         BuildConfigList buildConfigsList;
         if (!ObjectHelper.isEmpty(namespaceName)) {
             buildConfigsList = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).buildConfigs()
@@ -91,7 +102,7 @@ public class OpenshiftBuildConfigsProducer extends 
DefaultProducer {
 
     protected void doGetBuildConfig(Exchange exchange) {
         String buildConfigName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_BUILD_CONFIG_NAME, 
String.class);
-        String namespaceName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, 
String.class);
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
         if (ObjectHelper.isEmpty(buildConfigName)) {
             LOG.error("Get a specific Build Config require specify a Build 
Config name");
             throw new IllegalArgumentException("Get a specific Build Config 
require specify a Build Config name");
diff --git 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/builds/OpenshiftBuildsEndpoint.java
 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/builds/OpenshiftBuildsEndpoint.java
index 6ca7f6290ebf..febddab5c736 100644
--- 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/builds/OpenshiftBuildsEndpoint.java
+++ 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/builds/OpenshiftBuildsEndpoint.java
@@ -40,9 +40,9 @@ import static 
org.apache.camel.component.kubernetes.KubernetesConstants.SCHEME_B
 @BodyTypes(producerIn = @BodyType(value = Carrier.ANY,
                                   description = "Not used: the operation (the 
operation option, or else the"
                                                 + " CamelKubernetesOperation 
header) takes its input from headers: the"
-                                                + " namespace in 
CamelKubernetesNamespaceName, the name in"
-                                                + " CamelKubernetesBuildName 
and the labels in CamelKubernetesBuildsLabels. listBuilds does not"
-                                                + " read the namespace header: 
it lists the builds of all namespaces"),
+                                                + " namespace in 
CamelKubernetesNamespaceName (else the namespace option), the name in"
+                                                + " CamelKubernetesBuildName 
and the labels in CamelKubernetesBuildsLabels. Without a"
+                                                + " namespace the list 
operations list the builds of all namespaces"),
            producerOut = @BodyType(value = { Carrier.LIST, Carrier.POJO, 
Carrier.NULL },
                                    byOption = {
                                            @BodyType.When(option = 
"operation", value = "listBuilds", carriers = Carrier.LIST,
diff --git 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/builds/OpenshiftBuildsProducer.java
 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/builds/OpenshiftBuildsProducer.java
index 5a8d39524791..6fce7724fb17 100644
--- 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/builds/OpenshiftBuildsProducer.java
+++ 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/builds/OpenshiftBuildsProducer.java
@@ -70,13 +70,24 @@ public class OpenshiftBuildsProducer extends 
DefaultProducer {
     }
 
     protected void doList(Exchange exchange) {
-        BuildList buildList = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).builds().inAnyNamespace().list();
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
+        BuildList buildList;
+        if (!ObjectHelper.isEmpty(namespaceName)) {
+            buildList = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).builds().inNamespace(namespaceName)
+                    .list();
+        } else {
+            buildList = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).builds().inAnyNamespace().list();
+        }
         exchange.getMessage().setBody(buildList.getItems());
     }
 
     protected void doListBuildByLabels(Exchange exchange) {
         Map<String, String> labels = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_BUILDS_LABELS, 
Map.class);
-        String namespaceName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, 
String.class);
+        if (ObjectHelper.isEmpty(labels)) {
+            LOG.error("Listing Builds by labels requires specifying labels");
+            throw new IllegalArgumentException("Listing Builds by labels 
requires specifying labels");
+        }
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
         BuildList buildList;
         if (!ObjectHelper.isEmpty(namespaceName)) {
             buildList = getEndpoint().getKubernetesClient()
@@ -91,7 +102,7 @@ public class OpenshiftBuildsProducer extends DefaultProducer 
{
 
     protected void doGetBuild(Exchange exchange) {
         String buildName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_BUILD_NAME, 
String.class);
-        String namespaceName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, 
String.class);
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
         if (ObjectHelper.isEmpty(buildName)) {
             LOG.error("Get a specific Build require specify a Build name");
             throw new IllegalArgumentException("Get a specific Build require 
specify a Build name");
diff --git 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/deploymentconfigs/OpenshiftDeploymentConfigsEndpoint.java
 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/deploymentconfigs/OpenshiftDeploymentConfigsEndpoint.java
index 61dc7ce73a66..0f4c4e5b83bf 100644
--- 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/deploymentconfigs/OpenshiftDeploymentConfigsEndpoint.java
+++ 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/deploymentconfigs/OpenshiftDeploymentConfigsEndpoint.java
@@ -43,12 +43,12 @@ import static 
org.apache.camel.component.kubernetes.KubernetesConstants.SCHEME_D
            producerIn = @BodyType(value = Carrier.ANY,
                                   description = "Not used: the operation (the 
operation option, or else the"
                                                 + " CamelKubernetesOperation 
header) takes its input from headers: the"
-                                                + " namespace in 
CamelKubernetesNamespaceName, the name in"
+                                                + " namespace in 
CamelKubernetesNamespaceName (else the namespace option), the name in"
                                                 + " 
CamelKubernetesDeploymentName, the labels in"
                                                 + " 
CamelKubernetesDeploymentsLabels, the DeploymentConfigSpec in"
                                                 + " 
CamelKubernetesDeploymentConfigSpec and the replicas in"
-                                                + " 
CamelKubernetesDeploymentReplicas. The list and get operations do not read the 
namespace"
-                                                + " header: they use the 
namespace of the client"),
+                                                + " 
CamelKubernetesDeploymentReplicas. Without a namespace the list and get 
operations"
+                                                + " use the namespace of the 
client"),
            producerOut = @BodyType(value = { Carrier.LIST, Carrier.POJO, 
Carrier.NULL, Carrier.VALUE },
                                    byOption = {
                                            @BodyType.When(option = 
"operation", value = "listDeploymentConfigs",
@@ -76,8 +76,8 @@ import static 
org.apache.camel.component.kubernetes.KubernetesConstants.SCHEME_D
                                                  + " 
listDeploymentConfigsByLabels; the DeploymentConfig for"
                                                  + " getDeploymentConfig (null 
when not found), createDeploymentConfig and"
                                                  + " updateDeploymentConfig; a 
Boolean for deleteDeploymentConfig, false when"
-                                                 + " not found; for 
scaleDeploymentConfig the replicas of its status, as an"
-                                                 + " Integer"))
+                                                 + " not found; for 
scaleDeploymentConfig the replicas in the spec of the"
+                                                 + " scaled deployment config, 
as an Integer"))
 public class OpenshiftDeploymentConfigsEndpoint extends 
AbstractKubernetesEndpoint {
 
     public OpenshiftDeploymentConfigsEndpoint(String uri, 
OpenshiftDeploymentConfigsComponent component,
diff --git 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/deploymentconfigs/OpenshiftDeploymentConfigsProducer.java
 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/deploymentconfigs/OpenshiftDeploymentConfigsProducer.java
index ef588d2aedbb..0d0bf9f9973c 100644
--- 
a/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/deploymentconfigs/OpenshiftDeploymentConfigsProducer.java
+++ 
b/components/camel-kubernetes/src/main/java/org/apache/camel/component/openshift/deploymentconfigs/OpenshiftDeploymentConfigsProducer.java
@@ -21,12 +21,15 @@ import java.util.Map;
 import java.util.function.Function;
 
 import io.fabric8.kubernetes.api.model.StatusDetails;
+import io.fabric8.kubernetes.client.dsl.MixedOperation;
+import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
 import io.fabric8.kubernetes.client.dsl.Resource;
 import io.fabric8.openshift.api.model.DeploymentConfig;
 import io.fabric8.openshift.api.model.DeploymentConfigBuilder;
 import io.fabric8.openshift.api.model.DeploymentConfigList;
 import io.fabric8.openshift.api.model.DeploymentConfigSpec;
 import io.fabric8.openshift.client.OpenShiftClient;
+import io.fabric8.openshift.client.dsl.DeployableScalableResource;
 import org.apache.camel.Exchange;
 import org.apache.camel.component.kubernetes.AbstractKubernetesEndpoint;
 import org.apache.camel.component.kubernetes.KubernetesConstants;
@@ -93,16 +96,19 @@ public class OpenshiftDeploymentConfigsProducer extends 
DefaultProducer {
 
     protected void doList(Exchange exchange) {
         DeploymentConfigList deploymentConfigList
-                = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).deploymentConfigs().list();
+                = 
deploymentConfigs(KubernetesHelper.extractNamespace(getEndpoint(), 
exchange)).list();
         prepareOutboundMessage(exchange, deploymentConfigList.getItems());
     }
 
     protected void doListDeploymentConfigsByLabels(Exchange exchange) {
         Map<String, String> labels
                 = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_DEPLOYMENTS_LABELS, 
Map.class);
+        if (ObjectHelper.isEmpty(labels)) {
+            LOG.error("Listing Deployment Configs by labels requires 
specifying labels");
+            throw new IllegalArgumentException("Listing Deployment Configs by 
labels requires specifying labels");
+        }
         DeploymentConfigList deploymentConfigList
-                = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).deploymentConfigs()
-                        .withLabels(labels).list();
+                = 
deploymentConfigs(KubernetesHelper.extractNamespace(getEndpoint(), 
exchange)).withLabels(labels).list();
 
         prepareOutboundMessage(exchange, deploymentConfigList.getItems());
     }
@@ -113,7 +119,7 @@ public class OpenshiftDeploymentConfigsProducer extends 
DefaultProducer {
             LOG.error("Get a specific Deployment Config require specify a 
Deployment name");
             throw new IllegalArgumentException("Get a specific Deployment 
Config require specify a Deployment Config name");
         }
-        DeploymentConfig deploymentConfig = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).deploymentConfigs()
+        DeploymentConfig deploymentConfig = 
deploymentConfigs(KubernetesHelper.extractNamespace(getEndpoint(), exchange))
                 .withName(deploymentConfigName).get();
 
         prepareOutboundMessage(exchange, deploymentConfig);
@@ -121,7 +127,7 @@ public class OpenshiftDeploymentConfigsProducer extends 
DefaultProducer {
 
     protected void doDeleteDeploymentConfig(Exchange exchange) {
         String deploymentName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_DEPLOYMENT_NAME, 
String.class);
-        String namespaceName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, 
String.class);
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
         if (ObjectHelper.isEmpty(deploymentName)) {
             LOG.error("Delete a specific deployment config require specify a 
deployment name");
             throw new IllegalArgumentException("Delete a specific deployment 
require specify a deployment config name");
@@ -150,13 +156,13 @@ public class OpenshiftDeploymentConfigsProducer extends 
DefaultProducer {
     private void doCreateOrUpdateDeployment(
             Exchange exchange, String operationName, 
Function<Resource<DeploymentConfig>, DeploymentConfig> operation) {
         String deploymentName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_DEPLOYMENT_NAME, 
String.class);
-        String namespaceName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, 
String.class);
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
         DeploymentConfigSpec dcSpec
                 = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_DEPLOYMENT_CONFIG_SPEC,
 DeploymentConfigSpec.class);
         if (ObjectHelper.isEmpty(deploymentName)) {
             LOG.error("{} a specific Deployment Config require specify a 
Deployment name", operationName);
             throw new IllegalArgumentException(
-                    String.format("%s a specific Deployment Config require 
specify a pod name", operationName));
+                    String.format("%s a specific Deployment Config require 
specify a Deployment Config name", operationName));
         }
         if (ObjectHelper.isEmpty(namespaceName)) {
             LOG.error("{} a specific Deployment Config require specify a 
namespace name", operationName);
@@ -182,7 +188,7 @@ public class OpenshiftDeploymentConfigsProducer extends 
DefaultProducer {
 
     protected void doScaleDeploymentConfig(Exchange exchange) {
         String deploymentName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_DEPLOYMENT_NAME, 
String.class);
-        String namespaceName = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, 
String.class);
+        String namespaceName = 
KubernetesHelper.extractNamespace(getEndpoint(), exchange);
         Integer replicasNumber = 
exchange.getIn().getHeader(KubernetesConstants.KUBERNETES_DEPLOYMENT_REPLICAS, 
Integer.class);
         if (ObjectHelper.isEmpty(deploymentName)) {
             LOG.error("Scale a specific deployment config require specify a 
deployment config name");
@@ -201,6 +207,17 @@ public class OpenshiftDeploymentConfigsProducer extends 
DefaultProducer {
                         .inNamespace(namespaceName)
                         .withName(deploymentName).scale(replicasNumber);
 
-        prepareOutboundMessage(exchange, 
deploymentConfigScaled.getStatus().getReplicas());
+        // the replicas of the spec: the status may not be there yet, and lags 
behind until the pods are started or stopped
+        Integer replicas = deploymentConfigScaled != null && 
deploymentConfigScaled.getSpec() != null
+                ? deploymentConfigScaled.getSpec().getReplicas() : null;
+        prepareOutboundMessage(exchange, replicas != null ? replicas : 
replicasNumber);
+    }
+
+    private NonNamespaceOperation<DeploymentConfig, DeploymentConfigList, 
DeployableScalableResource<DeploymentConfig>> deploymentConfigs(
+            String namespace) {
+        MixedOperation<DeploymentConfig, DeploymentConfigList, 
DeployableScalableResource<DeploymentConfig>> operation
+                = 
getEndpoint().getKubernetesClient().adapt(OpenShiftClient.class).deploymentConfigs();
+        // without a namespace use the namespace of the client
+        return ObjectHelper.isEmpty(namespace) ? operation : 
operation.inNamespace(namespace);
     }
 }
diff --git 
a/components/camel-kubernetes/src/test/java/org/apache/camel/component/openshift/producer/OpenshiftProducersNamespaceTest.java
 
b/components/camel-kubernetes/src/test/java/org/apache/camel/component/openshift/producer/OpenshiftProducersNamespaceTest.java
new file mode 100644
index 000000000000..755a09b1bbfe
--- /dev/null
+++ 
b/components/camel-kubernetes/src/test/java/org/apache/camel/component/openshift/producer/OpenshiftProducersNamespaceTest.java
@@ -0,0 +1,298 @@
+/*
+ * 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.component.openshift.producer;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient;
+import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
+import io.fabric8.openshift.api.model.BuildBuilder;
+import io.fabric8.openshift.api.model.BuildConfigBuilder;
+import io.fabric8.openshift.api.model.DeploymentConfig;
+import io.fabric8.openshift.api.model.DeploymentConfigBuilder;
+import io.fabric8.openshift.api.model.DeploymentConfigSpecBuilder;
+import io.fabric8.openshift.client.OpenShiftClient;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.kubernetes.KubernetesConstants;
+import org.apache.camel.component.kubernetes.KubernetesTestSupport;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+ * The namespace of the openshift producers: the CamelKubernetesNamespaceName 
header, else the namespace option, else
+ * the namespace of the client (deployment configs) or all namespaces (builds 
and build configs).
+ */
+@EnableKubernetesMockClient(crud = true)
+class OpenshiftProducersNamespaceTest extends KubernetesTestSupport {
+
+    private static final Map<String, String> LABELS = Map.of("app", "demo");
+
+    NamespacedKubernetesClient client;
+
+    @BindToRegistry("kubernetesClient")
+    public NamespacedKubernetesClient getClient() {
+        return client;
+    }
+
+    @BeforeEach
+    void createResources() {
+        OpenShiftClient openShift = client.adapt(OpenShiftClient.class);
+        // the mock client uses the namespace "test"
+        for (String namespace : List.of("test", "other")) {
+            openShift.deploymentConfigs().inNamespace(namespace).resource(new 
DeploymentConfigBuilder().withNewMetadata()
+                    .withName("dc-" + 
namespace).withLabels(LABELS).endMetadata()
+                    .withSpec(new 
DeploymentConfigSpecBuilder().withReplicas(1).build()).build()).create();
+            openShift.builds().inNamespace(namespace).resource(new 
BuildBuilder().withNewMetadata()
+                    .withName("build-" + 
namespace).withLabels(LABELS).endMetadata().build()).create();
+            openShift.buildConfigs().inNamespace(namespace).resource(new 
BuildConfigBuilder().withNewMetadata()
+                    .withName("bc-" + 
namespace).withLabels(LABELS).endMetadata().build()).create();
+        }
+    }
+
+    @Test
+    void deploymentConfigsGetUsesNamespaceHeader() {
+        DeploymentConfig dc = template.requestBodyAndHeaders("direct:dc-get", 
null,
+                Map.of(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, "other",
+                        KubernetesConstants.KUBERNETES_DEPLOYMENT_NAME, 
"dc-other"),
+                DeploymentConfig.class);
+
+        assertNotNull(dc);
+        assertEquals("other", dc.getMetadata().getNamespace());
+    }
+
+    @Test
+    void deploymentConfigsGetUsesNamespaceOption() {
+        DeploymentConfig dc = 
template.requestBodyAndHeader("direct:dc-get-option", null,
+                KubernetesConstants.KUBERNETES_DEPLOYMENT_NAME, "dc-other", 
DeploymentConfig.class);
+
+        assertNotNull(dc);
+        assertEquals("other", dc.getMetadata().getNamespace());
+    }
+
+    @Test
+    void deploymentConfigsHeaderWinsOverNamespaceOption() {
+        DeploymentConfig dc = 
template.requestBodyAndHeaders("direct:dc-get-option", null,
+                Map.of(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, "test",
+                        KubernetesConstants.KUBERNETES_DEPLOYMENT_NAME, 
"dc-other"),
+                DeploymentConfig.class);
+
+        assertNull(dc);
+    }
+
+    @Test
+    void deploymentConfigsListUsesNamespaceHeader() {
+        List<?> result = template.requestBodyAndHeader("direct:dc-list", null,
+                KubernetesConstants.KUBERNETES_NAMESPACE_NAME, "other", 
List.class);
+
+        assertEquals(List.of("dc-other"), names(result));
+    }
+
+    @Test
+    void deploymentConfigsListWithoutNamespaceUsesClientNamespace() {
+        List<?> result = template.requestBody("direct:dc-list", null, 
List.class);
+
+        assertEquals(List.of("dc-test"), names(result));
+    }
+
+    @Test
+    void deploymentConfigsListByLabelsUsesNamespaceHeader() {
+        List<?> result = 
template.requestBodyAndHeaders("direct:dc-list-labels", null,
+                Map.of(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, "other",
+                        KubernetesConstants.KUBERNETES_DEPLOYMENTS_LABELS, 
LABELS),
+                List.class);
+
+        assertEquals(List.of("dc-other"), names(result));
+    }
+
+    @Test
+    void deploymentConfigsListByLabelsRequiresLabels() {
+        CamelExecutionException e = assertThrows(CamelExecutionException.class,
+                () -> template.requestBody("direct:dc-list-labels", ""));
+
+        assertInstanceOf(IllegalArgumentException.class, e.getCause());
+        assertEquals("Listing Deployment Configs by labels requires specifying 
labels", e.getCause().getMessage());
+    }
+
+    @Test
+    void deploymentConfigsCreateUsesNamespaceOption() {
+        DeploymentConfig dc = 
template.requestBodyAndHeaders("direct:dc-create-option", null,
+                Map.of(KubernetesConstants.KUBERNETES_DEPLOYMENT_NAME, 
"dc-new",
+                        KubernetesConstants.KUBERNETES_DEPLOYMENT_CONFIG_SPEC,
+                        new 
DeploymentConfigSpecBuilder().withReplicas(2).build()),
+                DeploymentConfig.class);
+
+        assertEquals("other", dc.getMetadata().getNamespace());
+        
assertNotNull(client.adapt(OpenShiftClient.class).deploymentConfigs().inNamespace("other").withName("dc-new").get());
+    }
+
+    @Test
+    void deploymentConfigsCreateRequiresName() {
+        CamelExecutionException e = assertThrows(CamelExecutionException.class,
+                () -> template.requestBody("direct:dc-create-option", ""));
+
+        assertInstanceOf(IllegalArgumentException.class, e.getCause());
+        assertEquals("Create a specific Deployment Config require specify a 
Deployment Config name",
+                e.getCause().getMessage());
+    }
+
+    @Test
+    void deploymentConfigsScaleWithoutStatusReturnsRequestedReplicas() {
+        Exchange exchange = template.request("direct:dc-scale", e -> {
+            e.getIn().setHeader(KubernetesConstants.KUBERNETES_NAMESPACE_NAME, 
"other");
+            
e.getIn().setHeader(KubernetesConstants.KUBERNETES_DEPLOYMENT_NAME, "dc-other");
+            
e.getIn().setHeader(KubernetesConstants.KUBERNETES_DEPLOYMENT_REPLICAS, 3);
+        });
+
+        assertNull(exchange.getException());
+        assertEquals(3, exchange.getMessage().getBody(Integer.class));
+        assertEquals(3, 
client.adapt(OpenShiftClient.class).deploymentConfigs().inNamespace("other").withName("dc-other")
+                .get().getSpec().getReplicas());
+    }
+
+    @Test
+    void buildsListUsesNamespaceHeader() {
+        List<?> result = template.requestBodyAndHeader("direct:builds-list", 
null,
+                KubernetesConstants.KUBERNETES_NAMESPACE_NAME, "other", 
List.class);
+
+        assertEquals(List.of("build-other"), names(result));
+    }
+
+    @Test
+    void buildsListUsesNamespaceOption() {
+        List<?> result = template.requestBody("direct:builds-list-option", 
null, List.class);
+
+        assertEquals(List.of("build-other"), names(result));
+    }
+
+    @Test
+    void buildsListWithoutNamespaceListsAllNamespaces() {
+        List<?> result = template.requestBody("direct:builds-list", null, 
List.class);
+
+        assertEquals(List.of("build-other", "build-test"), names(result));
+    }
+
+    @Test
+    void buildsGetUsesNamespaceOption() {
+        Object build = 
template.requestBodyAndHeader("direct:builds-get-option", null,
+                KubernetesConstants.KUBERNETES_BUILD_NAME, "build-other");
+
+        assertEquals("other", ((HasMetadata) 
build).getMetadata().getNamespace());
+    }
+
+    @Test
+    void buildsListByLabelsRequiresLabels() {
+        CamelExecutionException e = assertThrows(CamelExecutionException.class,
+                () -> template.requestBody("direct:builds-list-labels", ""));
+
+        assertInstanceOf(IllegalArgumentException.class, e.getCause());
+        assertEquals("Listing Builds by labels requires specifying labels", 
e.getCause().getMessage());
+    }
+
+    @Test
+    void buildConfigsListUsesNamespaceHeader() {
+        List<?> result = template.requestBodyAndHeader("direct:bc-list", null,
+                KubernetesConstants.KUBERNETES_NAMESPACE_NAME, "other", 
List.class);
+
+        assertEquals(List.of("bc-other"), names(result));
+    }
+
+    @Test
+    void buildConfigsListUsesNamespaceOption() {
+        List<?> result = template.requestBody("direct:bc-list-option", null, 
List.class);
+
+        assertEquals(List.of("bc-other"), names(result));
+    }
+
+    @Test
+    void buildConfigsListWithoutNamespaceListsAllNamespaces() {
+        List<?> result = template.requestBody("direct:bc-list", null, 
List.class);
+
+        assertEquals(List.of("bc-other", "bc-test"), names(result));
+    }
+
+    @Test
+    void buildConfigsGetUsesNamespaceOption() {
+        Object bc = template.requestBodyAndHeader("direct:bc-get-option", null,
+                KubernetesConstants.KUBERNETES_BUILD_CONFIG_NAME, "bc-other");
+
+        assertNotNull(bc);
+        assertEquals("other", ((HasMetadata) bc).getMetadata().getNamespace());
+    }
+
+    @Test
+    void buildConfigsListByLabelsUsesNamespaceOption() {
+        List<?> result = 
template.requestBodyAndHeader("direct:bc-list-labels-option", null,
+                KubernetesConstants.KUBERNETES_BUILD_CONFIGS_LABELS, LABELS, 
List.class);
+
+        assertEquals(List.of("bc-other"), names(result));
+    }
+
+    @Test
+    void buildConfigsListByLabelsRequiresLabels() {
+        CamelExecutionException e = assertThrows(CamelExecutionException.class,
+                () -> template.requestBody("direct:bc-list-labels", ""));
+
+        assertInstanceOf(IllegalArgumentException.class, e.getCause());
+        assertEquals("Listing Build Configs by labels requires specifying 
labels", e.getCause().getMessage());
+    }
+
+    private static List<String> names(List<?> resources) {
+        return resources.stream().map(r -> ((HasMetadata) 
r).getMetadata().getName()).sorted()
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                String dc = 
"openshift-deploymentconfigs:///?kubernetesClient=#kubernetesClient&operation=";
+                from("direct:dc-get").to(dc + "getDeploymentConfig");
+                from("direct:dc-get-option").to(dc + 
"getDeploymentConfig&namespace=other");
+                from("direct:dc-list").to(dc + "listDeploymentConfigs");
+                from("direct:dc-list-labels").to(dc + 
"listDeploymentConfigsByLabels");
+                from("direct:dc-create-option").to(dc + 
"createDeploymentConfig&namespace=other");
+                from("direct:dc-scale").to(dc + "scaleDeploymentConfig");
+
+                String builds = 
"openshift-builds:///?kubernetesClient=#kubernetesClient&operation=";
+                from("direct:builds-list").to(builds + "listBuilds");
+                from("direct:builds-list-option").to(builds + 
"listBuilds&namespace=other");
+                from("direct:builds-get-option").to(builds + 
"getBuild&namespace=other");
+                from("direct:builds-list-labels").to(builds + 
"listBuildsByLabels");
+
+                String bc = 
"openshift-build-configs:///?kubernetesClient=#kubernetesClient&operation=";
+                from("direct:bc-list").to(bc + "listBuildConfigs");
+                from("direct:bc-list-option").to(bc + 
"listBuildConfigs&namespace=other");
+                from("direct:bc-get-option").to(bc + 
"getBuildConfig&namespace=other");
+                from("direct:bc-list-labels").to(bc + 
"listBuildConfigsByLabels");
+                from("direct:bc-list-labels-option").to(bc + 
"listBuildConfigsByLabels&namespace=other");
+            }
+        };
+    }
+}
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index d08605de8402..6bd95d30e24a 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -744,6 +744,18 @@ for the other changes.
   `CamelKubernetesNodesLabels` header, the header that `listNodesByLabels` 
uses. Before, they read the
   `CamelKubernetesPodsLabels` header; a route that sets that header for a node 
must set
   `CamelKubernetesNodesLabels` instead.
+* The `openshift-builds`, `openshift-build-configs` and 
`openshift-deploymentconfigs` producers take the namespace
+  from the `CamelKubernetesNamespaceName` header, or else from the `namespace` 
endpoint option, in every operation.
+  Before, they ignored the option (used by the `openshift-deploymentconfigs` 
consumer only), `listBuilds` and
+  `listBuildConfigs` listed all namespaces even when a namespace was set, and 
`listDeploymentConfigs`,
+  `listDeploymentConfigsByLabels` and `getDeploymentConfig` always used the 
namespace of the Kubernetes client.
+  Without a namespace, `listBuilds` and `listBuildConfigs` still list all 
namespaces, and the deployment config
+  list and get operations still use the namespace of the client.
+* `listBuildsByLabels`, `listBuildConfigsByLabels` and 
`listDeploymentConfigsByLabels` without the labels header fail
+  with an `IllegalArgumentException` that says the labels are required, 
instead of a `NullPointerException`.
+* `scaleDeploymentConfig` returns the replicas of the spec of the scaled 
deployment config, the number that was asked
+  for. Before, it returned the replicas of its status, which lags behind until 
the pods are started or stopped, and
+  failed with a `NullPointerException` when the deployment config had no 
status yet.
 
 === camel-langchain4j-embeddingstore - auto-embedding a TextSegment, a List, a 
Map or a POJO body, and the REMOVE id
 

Reply via email to