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