diff --git a/README.md b/README.md index c3ae61b..aa2e105 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # Kubeflow Connector -A custom Camunda 8 outbound connector to communicate with the [Kubeflow](https://www.kubeflow.org/) API. It supports version 1 aqnd version 2 of the Kubeflow API and supports the functions mentioned below in the [API section](#api-section). +A custom Camunda 8 outbound connector to communicate with the [Kubeflow](https://www.kubeflow.org/) API. It supports the multi-user setup with profiles and namespaces as well as version 1 and 2 of the Kubeflow Pipeline API. It currently supports the functions mentioned below in the [API section](#api-section). -## Build +# Build and Run +## Build a deployable jar file You can package the Connector by running the following command: ```bash @@ -15,11 +16,38 @@ This will create the following artifacts: - A thin JAR without dependencies. - An fat JAR containing all dependencies, potentially shaded to avoid classpath conflicts. This will not include the SDK artifacts since those are in scope `provided` and will be brought along by the respective Connector Runtime executing the Connector. -## API -Currenty this connector supports the following methods from the Kubeflow Pipeline API. +### Shading dependencies + +You can use the `maven-shade-plugin` defined in the [Maven configuration](./pom.xml) to relocate common dependencies +that are used in other Connectors and the [Connector Runtime](https://github.com/camunda-community-hub/spring-zeebe/tree/master/connector-runtime#building-connector-runtime-bundles). +This helps to avoid classpath conflicts when the Connector is executed. + +Use the `relocations` configuration in the Maven Shade plugin to define the dependencies that should be shaded. +The [Maven Shade documentation](https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html) +provides more details on relocations. + +## Test locally + +Run unit tests + +```bash +mvn clean verify +``` + +## Test with local runtime +In your IDE you can also simply navigate to the `LocalContainerRuntime` class in test scope and run it via your IDE. +If necessary, you can adjust `application.properties` in test scope. + +### Configure a local environment for the Connector +The example bpmn models provided in the bpmn folder of the repository are set up in a way that they rely on environment variables being defined for the kubeflow and authentication configuration. We provided an [example.env](example.env) file that is tailored to the local development environment. You can copy this file to *.env* so that it is considered when you start the connector runtime locally. + + +# API +Currenty this connector supports the following methods from the Kubeflow Pipeline API in both API versions 1 and 2. - Get Pipelines - Get Experiments +- Get Experiment by ID - Get Runs - Get Run by ID - Get Run by Name @@ -27,55 +55,261 @@ Currenty this connector supports the following methods from the Kubeflow Pipelin - Start Run and Monitor - Create Experiment -### Get Pipelines +The inputs describes the parameters that can be set in the modeler for the operation. +The output is the complete output you will get written into the variable you enter under Output mapping in the result variable. In the result expression you can more specifically extract the data as required to limit the output. + +In every operation additional HTTP headers can be set under Kubeflow API -> HTTP Headers if necessary. + +## Get Pipelines ### Input +#### Parameter Filter (optional) + +API Version 1: + +```json +{ "predicates": + [ + { + "op":"IS_SUBSTRING", + "key": "name", + "string_value": "Control" + } + ] +} +``` + +API Version 2: +```json +{ "predicates": + [ + { + "operation":"IS_SUBSTRING", + "key": "name", + "string_value": "Control" + } + ] +} +``` +For details on filter structure and options check the proto-buffer files: + +Version 1: [https://github.com/kubeflow/pipelines/blob/master/backend/api/v1beta1/filter.proto](https://github.com/kubeflow/pipelines/blob/master/backend/api/v1beta1/filter.proto) + +Version 2: [https://github.com/kubeflow/pipelines/blob/master/backend/api/v2beta1/filter.proto](https://github.com/kubeflow/pipelines/blob/master/backend/api/v2beta1/filter.proto) +#### Parameter Namespace (optional) -| Name | Description | Example | Notes | -|----------|------------------|-------------------|----------------------------------------------------------------------------| -| filter | define the filter to apply to the call | `alice` | Has no effect on the function call outcome. | -| token | Mock token value | `my-secret-token` | Has no effect on the function call outcome. | -| message | Mock message | `Hello World` | Echoed back in the output. If starts with 'fail', an error will be thrown. | +API Version 1 and 2: If omitted, shared pipelines will also be returned. ### Output +API Version 1: [https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiListPipelinesResponse](https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiListPipelinesResponse) + +API Version 2: [https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#operation--apis-v2beta1-pipelines-get](https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#operation--apis-v2beta1-pipelines-get) + +## Get Experiments + +### Input + +#### Parameter Filter + +API Version 1: ```json -{ - "result": { - "myProperty": "Message received: ..." - } +{ "predicates": + [ + { + "op":"IS_SUBSTRING", + "key": "name", + "string_value": "test" + } + ] } ``` -### Error codes +API Version 2: +```json +{ "predicates": + [ + { + "operation":"IS_SUBSTRING", + "key": "name", + "string_value": "test" + } + ] +} +``` -| Code | Description | -|------|--------------------------------------------| -| FAIL | Message starts with 'fail' (ignoring case) | +#### Parameter Namespace (required in multiuser deployment) -## Test locally +API Version 1 and 2: namespace where the experiments should be retrieved from. -Run unit tests +### Output -```bash -mvn clean verify +API Version 1: [https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiListExperimentsResponse](https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiListExperimentsResponse) + +API Version 2: [https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1ListExperimentsResponse](https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1ListExperimentsResponse) + +## Get Experiment By ID + +### Input + +#### Parameter Experiment ID +The ID of the experiment that should be retrieved. + +### Output + +API Version 1: [https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiExperiment](https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiExperiment) + +API Version 2: [https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1Experiment](https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1Experiment) + +## Get Runs + +### Input + +#### Parameter Filter + +API Version 1: +```json +{ "predicates": + [ + { + "op":"IS_SUBSTRING", + "key": "name", + "string_value": "test" + } + ] +} +``` + +API Version 2: +```json +{ "predicates": + [ + { + "operation":"IS_SUBSTRING", + "key": "name", + "string_value": "test" + } + ] +} ``` -### Test with local runtime +#### Parameter Namespace (required in multiuser deployment) -Use the [Camunda Connector Runtime](https://github.com/camunda-community-hub/spring-zeebe/tree/master/connector-runtime#building-connector-runtime-bundles) to run your function as a local Java application. +API Version 1 and 2: namespace where the runs should be retrieved from. -In your IDE you can also simply navigate to the `LocalContainerRuntime` class in test scope and run it via your IDE. -If necessary, you can adjust `application.properties` in test scope. +### Output + +API Version 1: [https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiListRunsResponse](https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiListRunsResponse) + +API Version 2: [https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1ListRunsResponse](https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1ListRunsResponse) + + +## Get Run By ID + +### Input + +#### Parameter Run ID +The ID of the run that should be retrieved. + +### Output + +API Version 1: [https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiRunDetail](https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiRunDetail) + +API Version 2: [https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1Run](https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1Run) + +## Get Run By Name +This request tries to retrieve a single run by looking for a run that contains the name defined in the name parameter. + +### Input + +#### Parameter Name +The name to look for in the runs. This looks for the name to be equal. + +#### Parameter Namespace +The namespace where to look for runs. + +### Output +equal to responses of [Get Runs](#get-runs) + + +## Start Run +This operation starts a run and continues the process without waiting for the pipeline to finish. + +### Input + +#### Parameter Pipeline ID +The ID of the pipeline that should be run. + +#### Parameter Experiment ID +The ID of the experiment in which the run should be started. + +#### Parameter Suffix of run name +The name of the triggered run will be created as such: _. + +#### Parameter Run parameters (optional) +If the pipeline requires parameters to run they can be set here. + +### Output + +API Version 1: [https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiRunDetail](https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiRunDetail) + +API Version 2: [https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1Run](https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1Run) + +## Start Run and Monitor +This operation starts a run and monitors it until it finishes are throws an error. If the connector crashes during the run, the connector will pick up the already started run and monitor it after receiving the job again from Zeebe. + +### Input + +#### Parameter Pipeline ID +The ID of the pipeline that should be run. + +#### Parameter Experiment ID +The ID of the experiment in which the run should be started. + +#### Polling interval +You can define the interval in which the connector should regularly check the state of the run using ISO 8601 format. E. g. PT10S means every 10 seconds. + +#### Parameter Suffix of run name +The name of the triggered run will be created as such: _. + +#### Parameter Run parameters (optional) +If the pipeline requires parameters to run they can be set here. + +### Output +see [Start Run](#start-run) + +## Create Experiment +This operation allows to create an experiment, which can e. g. be used in a subsequent run. + +### Input + +#### Parameter Experiment Name +The name of the experiment to create. + +#### Parameter Experiment Description (optional) +The description of the experiment. + +#### Parameter Namespace +The namespace where to create the experiment in. + +### Output + +API Version 1: [https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiExperiment](https://www.kubeflow.org/docs/components/pipelines/v1/reference/api/kubeflow-pipeline-api-spec/#/definitions/apiExperiment) + +API Version 2: [https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1Experiment](https://www.kubeflow.org/docs/components/pipelines/v2/reference/api/kubeflow-pipeline-api-spec/#/definitions/v2beta1Experiment) + +## Error handling + +In case a return code >= 400 is returned by the API calls, the connector will raise an exception. ## Element Template The element templates can be found in the [kubeflow-connector.json](./element-templates/kubeflow-connector.json) file. # Local development environment setup -Start a local kubernets cluster e.g. with mimikube or kind. +Start a local kubernets cluster e.g. with minikube or kind. Run the following command from the root folder in order to deploy the dev environment into the kubernetes cluster. ```bash @@ -112,16 +346,4 @@ client-secret: Jq09L1liFa0UiaXnL3pcnXzlqOKXaoOW ``` ## Contact Information -For any queries and further support, please drop us a mail at [camunda8-connector-su-aaaamkuzw6jcci2hm7rscvue7y@viadee.slack.com](mailto:camunda8-connector-su-aaaamkuzw6jcci2hm7rscvue7y@viadee.slack.com) - -# OLD ========== - -### Shading dependencies - -You can use the `maven-shade-plugin` defined in the [Maven configuration](./pom.xml) to relocate common dependencies -that are used in other Connectors and the [Connector Runtime](https://github.com/camunda-community-hub/spring-zeebe/tree/master/connector-runtime#building-connector-runtime-bundles). -This helps to avoid classpath conflicts when the Connector is executed. - -Use the `relocations` configuration in the Maven Shade plugin to define the dependencies that should be shaded. -The [Maven Shade documentation](https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html) -provides more details on relocations. +For any queries and further support, please drop us a mail at [camunda8-connector-su-aaaamkuzw6jcci2hm7rscvue7y@viadee.slack.com](mailto:camunda8-connector-su-aaaamkuzw6jcci2hm7rscvue7y@viadee.slack.com) \ No newline at end of file diff --git a/bpmn/create_experiment.bpmn b/bpmn/create_experiment.bpmn index 360da8d..8c37784 100644 --- a/bpmn/create_experiment.bpmn +++ b/bpmn/create_experiment.bpmn @@ -1,5 +1,5 @@ - + Flow_0ar4k28 @@ -13,14 +13,13 @@ - - - - + + + + - diff --git a/bpmn/get_experiments.bpmn b/bpmn/get_experiments.bpmn index a7e8be0..78407b5 100644 --- a/bpmn/get_experiments.bpmn +++ b/bpmn/get_experiments.bpmn @@ -1,5 +1,5 @@ - + Flow_0xamqby @@ -9,12 +9,13 @@ - - - - + + + + - + + diff --git a/bpmn/get_pipelines.bpmn b/bpmn/get_pipelines.bpmn index 61fe149..f2a5a2d 100644 --- a/bpmn/get_pipelines.bpmn +++ b/bpmn/get_pipelines.bpmn @@ -9,16 +9,17 @@ - - - + + + - + + Flow_0xamqby diff --git a/bpmn/get_run_by_id.bpmn b/bpmn/get_run_by_id.bpmn index 1c22247..ea8c18c 100644 --- a/bpmn/get_run_by_id.bpmn +++ b/bpmn/get_run_by_id.bpmn @@ -1,5 +1,5 @@ - + Flow_0xamqby @@ -9,13 +9,13 @@ - - + + + - diff --git a/bpmn/get_run_by_name.bpmn b/bpmn/get_run_by_name.bpmn index cf026ef..7a3b0fe 100644 --- a/bpmn/get_run_by_name.bpmn +++ b/bpmn/get_run_by_name.bpmn @@ -1,5 +1,5 @@ - + Flow_0xamqby @@ -9,13 +9,13 @@ - - - + + + + - diff --git a/bpmn/get_runs.bpmn b/bpmn/get_runs.bpmn index 9462b3f..64f33ac 100644 --- a/bpmn/get_runs.bpmn +++ b/bpmn/get_runs.bpmn @@ -1,5 +1,5 @@ - + Flow_0xamqby @@ -9,12 +9,12 @@ - - - + + + - + diff --git a/bpmn/start_run.bpmn b/bpmn/start_run.bpmn index 2e13bb4..b0b4fdc 100644 --- a/bpmn/start_run.bpmn +++ b/bpmn/start_run.bpmn @@ -1,5 +1,5 @@ - + Flow_18a4hsh @@ -9,15 +9,15 @@ - - + + + - diff --git a/bpmn/start_run_and_monitor.bpmn b/bpmn/start_run_and_monitor.bpmn index ad31b8d..2f3f141 100644 --- a/bpmn/start_run_and_monitor.bpmn +++ b/bpmn/start_run_and_monitor.bpmn @@ -1,5 +1,5 @@ - + Flow_0ppmo2y @@ -27,16 +27,16 @@ - - + + + - diff --git a/deployEnv.sh b/deployEnv.sh index 3100d43..068bc58 100755 --- a/deployEnv.sh +++ b/deployEnv.sh @@ -19,6 +19,7 @@ done kubectl wait --for=condition=available --timeout=300s deployment --all --all-namespaces printf "\n\nDeployment finished!\n\n" +sed -i '' 's/'"$KUBEFLOW_HOST"':3000/${KUBEFLOW_HOST}:3000/g' ./src/test/resources/kubeflow-environment/oauth2_proxy.yml printf "Checking if NodePort is reachable on localhost...\n\n" if nc -v -z -w2 localhost 30000 &> /dev/null; then diff --git a/element-templates/kubeflow-connector.json b/element-templates/kubeflow-connector.json index 52bf60e..22fb8cf 100644 --- a/element-templates/kubeflow-connector.json +++ b/element-templates/kubeflow-connector.json @@ -450,6 +450,31 @@ ] } }, + { + "id": "kubeflowapi.namespace", + "label": "Namespace", + "description": "Specify the name of the namespace.", + "type": "String", + "group": "kubeflowapi", + "feel": "optional", + "optional": true, + "binding": { + "type": "zeebe:input", + "name": "kubeflowapi.namespace" + }, + "condition": { + "allMatch": [ + { + "property": "configuration.typeOfUserMode", + "equals": "multiUserMode" + }, + { + "property": "kubeflowapi.operation", + "oneOf": ["get_pipelines"] + } + ] + } + }, { "id": "kubeflowapi.pipelineId", "label": "Pipeline ID", diff --git a/example.env b/example.env new file mode 100644 index 0000000..1d44563 --- /dev/null +++ b/example.env @@ -0,0 +1,14 @@ +KF_CONNECTOR_URL=http://localhost:30000 + +KF_AUTH_MODE=oauth_cc +KF_AUTH_BASIC_USERNAME= +KF_AUTH_BASIC_PASSWORD= +KF_AUTH_BEARER_TOKEN= +KF_AUTH_OAUTH_TOKEN_ENDPOINT=http://localhost:30000/auth/realms/kubeflow/protocol/openid-connect/token +KF_AUTH_OAUTH_CLIENT_ID=kubeflow +KF_AUTH_OAUTH_CLIENT_SECRET=Jq09L1liFa0UiaXnL3pcnXzlqOKXaoOW +KF_AUTH_OAUTH_SCOPES=openid email profile groups +KF_AUTH_OAUTH_AUDIENCE=kubeflow +KF_AUTH_OAUTH_CLIENT_AUTH=basicAuthHeader +KF_AUTH_OAUTH_USERNAME= +KF_AUTH_OAUTH_PASSWORD= \ No newline at end of file diff --git a/pom.xml b/pom.xml index 6f370fe..fc6c412 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ UTF-8 UTF-8 - 8.3.7 + 8.3.8 3.24.2 5.10.0 diff --git a/src/it/de/viadee/bpm/camunda/connectors/kubeflow/integration/BaseIntegrationTest.java b/src/it/de/viadee/bpm/camunda/connectors/kubeflow/integration/BaseIntegrationTest.java index 42d227e..7679117 100644 --- a/src/it/de/viadee/bpm/camunda/connectors/kubeflow/integration/BaseIntegrationTest.java +++ b/src/it/de/viadee/bpm/camunda/connectors/kubeflow/integration/BaseIntegrationTest.java @@ -82,7 +82,10 @@ protected Configuration getConfiguration() { protected KubeflowConnectorExecutor getExecutor(String pipelineVersion, String operation, String experimentName, String pipelineId, String experimentId, String runName) throws Exception { - var namespace = getEnvOrDefault(KUBEFLOW_NAMESPACE_ENV_KEY, DEFAULT_KUBEFLOW_NAMESPACE); + var namespace = ""; + if (!operation.equals("get_pipelines")) { + namespace = getEnvOrDefault(KUBEFLOW_NAMESPACE_ENV_KEY, DEFAULT_KUBEFLOW_NAMESPACE); + } KubeflowApi kubeflowApi = new KubeflowApi(pipelineVersion, operation, null, runName, null, pipelineId, experimentId, null, null, experimentName, null, null, namespace); KubeflowConnectorRequest kubeflowConnectorRequest = new KubeflowConnectorRequest( diff --git a/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/KubeflowConnectorFunction.java b/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/KubeflowConnectorFunction.java index be3746f..1b5c3bb 100644 --- a/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/KubeflowConnectorFunction.java +++ b/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/KubeflowConnectorFunction.java @@ -32,7 +32,7 @@ public Object execute(final OutboundConnectorContext context) HttpResponse response = connectorExecutor.execute(); // raise error based on status code - if (response.statusCode() >= 300) { + if (response.statusCode() >= 400) { throw new RuntimeException(response.body()); } diff --git a/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/entities/input/KubeflowApi.java b/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/entities/input/KubeflowApi.java index eafaa7f..9a11e63 100644 --- a/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/entities/input/KubeflowApi.java +++ b/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/entities/input/KubeflowApi.java @@ -2,6 +2,7 @@ import java.util.Map; +import io.camunda.connector.feel.annotation.FEEL; import jakarta.validation.constraints.NotEmpty; public record KubeflowApi( @@ -21,6 +22,7 @@ public record KubeflowApi( String experimentId, + @FEEL String filter, String pollingInterval, diff --git a/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/services/KubeflowConnectorExecutor.java b/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/services/KubeflowConnectorExecutor.java index 8cf7602..185e63c 100644 --- a/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/services/KubeflowConnectorExecutor.java +++ b/src/main/java/de/viadee/bpm/camunda/connectors/kubeflow/services/KubeflowConnectorExecutor.java @@ -73,7 +73,7 @@ public KubeflowConnectorExecutor(KubeflowConnectorRequest connectorRequest, long public HttpResponse execute() { try { HttpResponse response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); - if (response.statusCode() >= 300) { + if (response.statusCode() >= 400) { throw new RuntimeException("Error while running request against kubeflow server: " + httpRequest.uri() + " - " + response.body()); } @@ -190,19 +190,24 @@ private void addFilter(URIBuilder uriBuilder) throws UnsupportedEncodingExceptio protected void addNamespaceFilter(URIBuilder uriBuilder) { if (isMultiUserMode) { - if (kubeflowApiOperationsEnum.isNamespaceFilterRequired()) { - var namespace = connectorRequest.getKubeflowapi().namespace(); - if (KubeflowApisEnum.PIPELINES_V1.equals(kubeflowApisEnum)) { - uriBuilder.addParameter(URI_PARAMETER_PAIR_V1_TYPE_NS.getKey(), - URI_PARAMETER_PAIR_V1_TYPE_NS.getValue()); - uriBuilder.addParameter(URI_PARAMETER_V1_ID, namespace); - } else { - uriBuilder.addParameter(URI_PARAMETER_V2_NS, namespace); - } + var namespace = connectorRequest.getKubeflowapi().namespace(); + if (kubeflowApiOperationsEnum.isNamespaceFilterRequired() || + (KubeflowApiOperationsEnum.GET_PIPELINES.equals(kubeflowApiOperationsEnum) && namespace != null)) { + setNamespaceParameter(uriBuilder, namespace); } } } + private void setNamespaceParameter(URIBuilder uriBuilder, String namespace) { + if (KubeflowApisEnum.PIPELINES_V1.equals(kubeflowApisEnum)) { + uriBuilder.addParameter(URI_PARAMETER_PAIR_V1_TYPE_NS.getKey(), + URI_PARAMETER_PAIR_V1_TYPE_NS.getValue()); + uriBuilder.addParameter(URI_PARAMETER_V1_ID, namespace); + } else { + uriBuilder.addParameter(URI_PARAMETER_V2_NS, namespace); + } + } + public static HttpRequest.BodyPublisher ofFormData(Map data) { var builder = new StringBuilder(); for (Map.Entry entry : data.entrySet()) {