This is an automated email from the ASF dual-hosted git repository.
jshao pushed a commit to branch branch-1.0
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-1.0 by this push:
new 154d35a0b7 [#8642] feat(doc): Add the IT and doc for job template
alteration (#8810)
154d35a0b7 is described below
commit 154d35a0b70db5335dd2294e11224cff227aac2f
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Tue Oct 14 14:08:42 2025 +0800
[#8642] feat(doc): Add the IT and doc for job template alteration (#8810)
### What changes were proposed in this pull request?
This PR adds the IT and docs for job template alteration.
### Why are the changes needed?
This is the final PR for job template alteration.
Fix: #8642
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
ITs.
Co-authored-by: Jerry Shao <[email protected]>
---
.../gravitino/client/integration/test/JobIT.java | 106 +++++
.../gravitino/client/dto_converters.py | 8 +-
.../tests/integration/test_supports_jobs.py | 110 ++++++
docs/manage-jobs-in-gravitino.md | 89 +++++
docs/open-api/jobs.yaml | 440 +++++++++++++++++----
5 files changed, 662 insertions(+), 91 deletions(-)
diff --git
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/JobIT.java
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/JobIT.java
index 59043422aa..f5e66b304d 100644
---
a/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/JobIT.java
+++
b/clients/client-java/src/test/java/org/apache/gravitino/client/integration/test/JobIT.java
@@ -37,6 +37,7 @@ import org.apache.gravitino.integration.test.util.BaseIT;
import org.apache.gravitino.integration.test.util.GravitinoITUtils;
import org.apache.gravitino.job.JobHandle;
import org.apache.gravitino.job.JobTemplate;
+import org.apache.gravitino.job.JobTemplateChange;
import org.apache.gravitino.job.ShellJobTemplate;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
@@ -177,6 +178,111 @@ public class JobIT extends BaseIT {
Assertions.assertTrue(registeredTemplates.isEmpty());
}
+ @Test
+ public void testRegisterAndAlterJobTemplate() {
+ ShellJobTemplate template = builder.withName("test_alter").build();
+ Assertions.assertDoesNotThrow(() ->
metalake.registerJobTemplate(template));
+
+ // Rename the job template
+ JobTemplate renamedTemplate =
+ metalake.alterJobTemplate(template.name(),
JobTemplateChange.rename("renamed_test_alter"));
+
+ // Verify the job template is renamed
+ Assertions.assertEquals("renamed_test_alter", renamedTemplate.name());
+ Assertions.assertEquals(template.comment(), renamedTemplate.comment());
+ Assertions.assertEquals(template.executable(),
renamedTemplate.executable());
+ Assertions.assertEquals(template.arguments(), renamedTemplate.arguments());
+ Assertions.assertEquals(template.environments(),
renamedTemplate.environments());
+ Assertions.assertEquals(template.customFields(),
renamedTemplate.customFields());
+ Assertions.assertEquals(template.scripts(), ((ShellJobTemplate)
renamedTemplate).scripts());
+
+ JobTemplate fetchedTemplate =
metalake.getJobTemplate(renamedTemplate.name());
+ Assertions.assertEquals(renamedTemplate, fetchedTemplate);
+
+ // Update the job template's comment
+ JobTemplate updatedTemplate =
+ metalake.alterJobTemplate(
+ renamedTemplate.name(), JobTemplateChange.updateComment("Updated
comment"));
+
+ // Verify the job template comment is updated
+ Assertions.assertEquals("Updated comment", updatedTemplate.comment());
+ Assertions.assertEquals(renamedTemplate.name(), updatedTemplate.name());
+ Assertions.assertEquals(template.executable(),
updatedTemplate.executable());
+ Assertions.assertEquals(template.arguments(), updatedTemplate.arguments());
+ Assertions.assertEquals(template.environments(),
updatedTemplate.environments());
+ Assertions.assertEquals(template.customFields(),
updatedTemplate.customFields());
+ Assertions.assertEquals(template.scripts(), ((ShellJobTemplate)
updatedTemplate).scripts());
+
+ // Fetch the updated template and verify
+ JobTemplate fetchedUpdatedTemplate =
metalake.getJobTemplate(updatedTemplate.name());
+ Assertions.assertEquals(updatedTemplate, fetchedUpdatedTemplate);
+
+ // Update the job template's executable, arguments, and environments
+ JobTemplateChange.ShellTemplateUpdate update =
+ JobTemplateChange.ShellTemplateUpdate.builder()
+ .withNewExecutable("/new/path/to/executable.sh")
+ .withNewArguments(Lists.newArrayList("newArg1", "newArg2"))
+ .withNewEnvironments(ImmutableMap.of("NEW_ENV", "newValue"))
+ .build();
+
+ JobTemplate modifiedTemplate =
+ metalake.alterJobTemplate(updatedTemplate.name(),
JobTemplateChange.updateTemplate(update));
+
+ // Verify the job template fields are updated
+ Assertions.assertEquals(update.getNewExecutable(),
modifiedTemplate.executable());
+ Assertions.assertEquals(update.getNewArguments(),
modifiedTemplate.arguments());
+ Assertions.assertEquals(update.getNewEnvironments(),
modifiedTemplate.environments());
+ Assertions.assertEquals(updatedTemplate.customFields(),
modifiedTemplate.customFields());
+ Assertions.assertEquals(
+ ((ShellJobTemplate) updatedTemplate).scripts(),
+ ((ShellJobTemplate) modifiedTemplate).scripts());
+
+ // Fetch the modified template and verify
+ JobTemplate fetchedModifiedTemplate =
metalake.getJobTemplate(modifiedTemplate.name());
+ Assertions.assertEquals(modifiedTemplate, fetchedModifiedTemplate);
+
+ // Update the job template's custom fields and scripts
+ JobTemplateChange.ShellTemplateUpdate update1 =
+ JobTemplateChange.ShellTemplateUpdate.builder()
+ .withNewCustomFields(ImmutableMap.of("customKey", "customValue"))
+ .withNewScripts(Lists.newArrayList(testLibScriptPath,
"/new/path/to/script.sh"))
+ .build();
+
+ JobTemplate finalTemplate =
+ metalake.alterJobTemplate(
+ modifiedTemplate.name(),
JobTemplateChange.updateTemplate(update1));
+
+ // Verify the job template fields are updated
+ Assertions.assertEquals(modifiedTemplate.executable(),
finalTemplate.executable());
+ Assertions.assertEquals(modifiedTemplate.arguments(),
finalTemplate.arguments());
+ Assertions.assertEquals(modifiedTemplate.environments(),
finalTemplate.environments());
+ Assertions.assertEquals(update1.getNewCustomFields(),
finalTemplate.customFields());
+ Assertions.assertEquals(update1.getNewScripts(), ((ShellJobTemplate)
finalTemplate).scripts());
+
+ // Fetch the final template and verify
+ JobTemplate fetchedFinalTemplate =
metalake.getJobTemplate(finalTemplate.name());
+ Assertions.assertEquals(finalTemplate, fetchedFinalTemplate);
+
+ // Test altering a non-existent job template
+ Assertions.assertThrows(
+ NoSuchJobTemplateException.class,
+ () ->
+ metalake.alterJobTemplate(
+ "non_existent_template",
JobTemplateChange.rename("new_name")));
+
+ // Test altering with wrong change type
+ JobTemplateChange.SparkTemplateUpdate wrongUpdate =
+ JobTemplateChange.SparkTemplateUpdate.builder()
+ .withNewClassName("com.example.Main")
+ .build();
+
+ Assertions.assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ metalake.alterJobTemplate(
+ finalTemplate.name(),
JobTemplateChange.updateTemplate(wrongUpdate)));
+ }
+
@Test
public void testRunAndListJobs() {
JobTemplate template = builder.withName("test_run").build();
diff --git a/clients/client-python/gravitino/client/dto_converters.py
b/clients/client-python/gravitino/client/dto_converters.py
index 5283075318..9b0c3775c6 100644
--- a/clients/client-python/gravitino/client/dto_converters.py
+++ b/clients/client-python/gravitino/client/dto_converters.py
@@ -143,7 +143,7 @@ class DTOConverters:
)
@staticmethod
- def _to_shell_job_template(template: JobTemplate) -> ShellJobTemplate:
+ def to_shell_job_template(template: JobTemplate) -> ShellJobTemplate:
if isinstance(template, ShellJobTemplate):
return template
@@ -152,7 +152,7 @@ class DTOConverters:
)
@staticmethod
- def _to_spark_job_template(template: JobTemplate) -> SparkJobTemplate:
+ def to_spark_job_template(template: JobTemplate) -> SparkJobTemplate:
if isinstance(template, SparkJobTemplate):
return template
@@ -199,7 +199,7 @@ class DTOConverters:
@staticmethod
def to_job_template_dto(template: JobTemplate) -> JobTemplateDTO:
if isinstance(template, ShellJobTemplate):
- shell_template = DTOConverters._to_shell_job_template(template)
+ shell_template = DTOConverters.to_shell_job_template(template)
return ShellJobTemplateDTO(
_job_type=shell_template.job_type(),
_name=shell_template.name,
@@ -212,7 +212,7 @@ class DTOConverters:
)
if isinstance(template, SparkJobTemplate):
- spark_template = DTOConverters._to_spark_job_template(template)
+ spark_template = DTOConverters.to_spark_job_template(template)
return SparkJobTemplateDTO(
_job_type=spark_template.job_type(),
_name=spark_template.name,
diff --git a/clients/client-python/tests/integration/test_supports_jobs.py
b/clients/client-python/tests/integration/test_supports_jobs.py
index 2235050b58..4a5195a530 100644
--- a/clients/client-python/tests/integration/test_supports_jobs.py
+++ b/clients/client-python/tests/integration/test_supports_jobs.py
@@ -23,11 +23,18 @@ from time import sleep
from gravitino import GravitinoAdminClient, GravitinoMetalake
from gravitino.api.job.job_handle import JobHandle
+from gravitino.api.job.job_template_change import (
+ JobTemplateChange,
+ ShellTemplateUpdate,
+ SparkTemplateUpdate,
+)
from gravitino.api.job.shell_job_template import ShellJobTemplate
+from gravitino.client.dto_converters import DTOConverters
from gravitino.exceptions.base import (
JobTemplateAlreadyExistsException,
NoSuchJobTemplateException,
NoSuchJobException,
+ IllegalArgumentException,
)
from tests.integration.integration_test_env import IntegrationTestEnv
@@ -160,6 +167,109 @@ class TestSupportsJobs(IntegrationTestEnv):
registered_templates = self._metalake.list_job_templates()
self.assertTrue(len(registered_templates) == 0)
+ def test_register_and_alter_job_template(self):
+ template = self.builder.with_name("test_alter").build()
+ self._metalake.register_job_template(template)
+
+ # Rename the job template
+ updated_template = self._metalake.alter_job_template(
+ template.name, JobTemplateChange.rename("test_alter_renamed")
+ )
+ self.assertEqual("test_alter_renamed", updated_template.name)
+ self.assertEqual(template.executable, updated_template.executable)
+ self.assertEqual(template.arguments, updated_template.arguments)
+ self.assertEqual(template.environments, updated_template.environments)
+ self.assertEqual(template.custom_fields,
updated_template.custom_fields)
+ self.assertEqual(
+ template.scripts,
+ DTOConverters.to_shell_job_template(updated_template).scripts,
+ )
+
+ fetched_template =
self._metalake.get_job_template("test_alter_renamed")
+ self.assertEqual(updated_template, fetched_template)
+
+ # Update the comment of the job template
+ updated_template = self._metalake.alter_job_template(
+ "test_alter_renamed", JobTemplateChange.update_comment("Updated
comment")
+ )
+ self.assertEqual("Updated comment", updated_template.comment)
+ self.assertEqual("test_alter_renamed", updated_template.name)
+ self.assertEqual(template.executable, updated_template.executable)
+ self.assertEqual(template.arguments, updated_template.arguments)
+ self.assertEqual(template.environments, updated_template.environments)
+ self.assertEqual(template.custom_fields,
updated_template.custom_fields)
+ self.assertEqual(
+ template.scripts,
+ DTOConverters.to_shell_job_template(updated_template).scripts,
+ )
+
+ fetched_template =
self._metalake.get_job_template("test_alter_renamed")
+ self.assertEqual(updated_template, fetched_template)
+
+ # Update the content of the job template
+ updated_template_content = ShellTemplateUpdate(
+ new_executable="/bin/echo",
+ new_arguments=["Hello", "World"],
+ new_environments={"NEW_ENV": "new_value"},
+ )
+ updated_template = self._metalake.alter_job_template(
+ "test_alter_renamed",
+ JobTemplateChange.update_template(updated_template_content),
+ )
+
+ self.assertEqual("/bin/echo", updated_template.executable)
+ self.assertEqual(["Hello", "World"], updated_template.arguments)
+ self.assertEqual({"NEW_ENV": "new_value"},
updated_template.environments)
+ self.assertEqual("Updated comment", updated_template.comment)
+ self.assertEqual("test_alter_renamed", updated_template.name)
+ self.assertEqual(template.custom_fields,
updated_template.custom_fields)
+ self.assertEqual(
+ template.scripts,
+ DTOConverters.to_shell_job_template(updated_template).scripts,
+ )
+
+ fetched_template =
self._metalake.get_job_template("test_alter_renamed")
+ self.assertEqual(updated_template, fetched_template)
+
+ # Update the custom fields and scripts of the job template
+ updated_template_content = ShellTemplateUpdate(
+ new_custom_fields={"key1": "value1", "key2": "value2"},
+ new_scripts=["/bin/script1.sh", "/bin/script2.sh"],
+ )
+ updated_template = self._metalake.alter_job_template(
+ "test_alter_renamed",
+ JobTemplateChange.update_template(updated_template_content),
+ )
+
+ self.assertEqual("/bin/echo", updated_template.executable)
+ self.assertEqual(["Hello", "World"], updated_template.arguments)
+ self.assertEqual({"NEW_ENV": "new_value"},
updated_template.environments)
+ self.assertEqual("Updated comment", updated_template.comment)
+ self.assertEqual("test_alter_renamed", updated_template.name)
+ self.assertEqual(
+ {"key1": "value1", "key2": "value2"},
updated_template.custom_fields
+ )
+ self.assertEqual(
+ ["/bin/script1.sh", "/bin/script2.sh"],
+ DTOConverters.to_shell_job_template(updated_template).scripts,
+ )
+
+ fetched_template =
self._metalake.get_job_template("test_alter_renamed")
+ self.assertEqual(updated_template, fetched_template)
+
+ # Test altering a non-existent job template
+ with self.assertRaises(NoSuchJobTemplateException):
+ self._metalake.alter_job_template(
+ "non_existent", JobTemplateChange.rename("should_fail")
+ )
+
+ # Test altering with the wrong type of change
+ with self.assertRaises(IllegalArgumentException):
+ wrong_update = SparkTemplateUpdate(new_executable="/bin/echo")
+ self._metalake.alter_job_template(
+ "test_alter_renamed",
JobTemplateChange.update_template(wrong_update)
+ )
+
def test_run_and_list_jobs(self):
template = self.builder.with_name("test_run").build()
self._metalake.register_job_template(template)
diff --git a/docs/manage-jobs-in-gravitino.md b/docs/manage-jobs-in-gravitino.md
index 271dc6019d..d94ad6d204 100644
--- a/docs/manage-jobs-in-gravitino.md
+++ b/docs/manage-jobs-in-gravitino.md
@@ -343,6 +343,95 @@ curl -X DELETE -H "Accept:
application/vnd.gravitino.v1+json" \
</TabItem>
</Tabs>
+### Alter a registered job template
+
+You can alter a registered job template by its name using the REST API or the
Java and Python
+SDKs. Gravitino supports altering the `name`, `comment` and `template` fields
of the job template.
+
+<Tabs groupId='language' queryString>
+<TabItem value="shell" label="Shell">
+
+```shell
+curl -X PUT -H "Accept: application/vnd.gravitino.v1+json" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "updates": [
+ {
+ "@type": "rename",
+ "newName": "altered_shell_job_template"
+ },
+ {
+ "@type": "comment",
+ "newComment": "An altered shell job template"
+ },
+ {
+ "@type": "updateTemplate",
+ "newTemplate": {
+ "@type": "shell",
+ "newExecutable": "/new/path/to/my_script.sh",
+ "newArguments": ["{{new_arg1}}", "{{new_arg2}}"],
+ "newEnvironments": {
+ "NEW_ENV_VAR1": "{{new_value1}}",
+ "NEW_ENV_VAR2": "{{new_value2}}"
+ },
+ "newCustomFields": {
+ "new_field1": "{{new_value1}}",
+ "new_field2": "{{new_value2}}"
+ },
+ "newScripts": ["/new/path/to/script1.sh",
"/new/path/to/script2.sh"]
+ }
+ }
+ ]
+
+ }'
http://localhost:8090/api/metalakes/test/jobs/templates/my_shell_job_template
+```
+
+</TabItem>
+<TabItem value="java" label="Java">
+
+```java
+ ShellTemplateUpdate newTemplate = ShellTemplateUpdate.builder()
+ .withNewExecutable("/new/path/to/my_script.sh")
+ .withNewArguments(ImmutableList.of("{{new_arg1}}", "{{new_arg2}}"))
+ .withNewEnvironments(ImmutableMap.of("NEW_ENV_VAR1", "{{new_value1}}",
"NEW_ENV_VAR2", "{{new_value2}}"))
+ .withNewCustomFields(ImmutableMap.of("new_field1", "{{new_value1}}",
"new_field2", "{{new_value2}}"))
+ .withNewScripts(List.of("/new/path/to/script1.sh",
"/new/path/to/script2.sh"))
+ .build();
+
+ List<JobTemplateChange> changes = List.of(
+ JobTemplateChange.rename("altered_shell_job_template"),
+ JobTemplateChange.updateComment("An altered shell job template"),
+ JobTemplateChange.updateTemplateUpdateJobTemplate(newTemplate));
+
+ GravitinoClient client = ...;
+ client.alterJobTemplate("my_shell_job_template", changes);
+```
+
+</TabItem>
+<TabItem value="python" label="Python">
+
+```python
+ new_template = ShellTemplateUpdate(
+ new_executable="/new/path/to/my_script.sh",
+ new_arguments=["{{new_arg1}}", "{{new_arg2}}"],
+ new_environments={"NEW_ENV_VAR1": "{{new_value1}}", "NEW_ENV_VAR2":
"{{new_value2}}"},
+ new_custom_fields={"new_field1": "{{new_value1}}", "new_field2":
"{{new_value2}}"},
+ new_scripts=["/new/path/to/script1.sh", "/new/path/to/script2.sh"]
+ )
+
+ changes = [
+ JobTemplateChange.rename("altered_shell_job_template"),
+ JobTemplateChange.update_comment("An altered shell job template"),
+ JobTemplateChange.update_template(new_template)
+ ]
+
+ client = GravitinoClient(...)
+ client.alter_job_template("my_shell_job_template", changes)
+```
+
+</TabItem>
+</Tabs>
+
### Run a job based on a job template
To run a job based on the registered job template, you can use the REST API or
the Java and Python SDKs.
diff --git a/docs/open-api/jobs.yaml b/docs/open-api/jobs.yaml
index d5be5bc109..951cda10c5 100644
--- a/docs/open-api/jobs.yaml
+++ b/docs/open-api/jobs.yaml
@@ -137,6 +137,54 @@ paths:
"5xx":
$ref: "./openapi.yaml#/components/responses/ServerErrorResponse"
+ put:
+ tags:
+ - job
+ summary: Update job template
+ operationId: updateJobTemplate
+ description: Updates a job template in the specified metalake
+ requestBody:
+ content:
+ application/vnd.gravitino.v1+json:
+ schema:
+ $ref: "#/components/requests/JobTemplateUpdatesRequest"
+ examples:
+ JobTemplateRegisterRequest:
+ $ref: "#/components/examples/JobTemplateUpdatesRequest"
+
+ responses:
+ "200":
+ description: Returns the updated job template object
+ content:
+ application/vnd.gravitino.v1+json:
+ schema:
+ $ref: "#/components/responses/JobTemplateResponse"
+ examples:
+ JobTemplateResponse:
+ $ref: "#/components/examples/JobTemplateResponse"
+ "404":
+ description: Not Found - The specified job template does not exist
in the specified metalake
+ content:
+ application/vnd.gravitino.v1+json:
+ schema:
+ $ref: "./openapi.yaml#/components/schemas/ErrorModel"
+ examples:
+ NoSuchMetalakeException:
+ $ref:
"./metalakes.yaml#/components/examples/NoSuchMetalakeException"
+ NoSuchJobTemplateException:
+ $ref: "#/components/examples/NoSuchJobTemplateException"
+ "400":
+ description: Bad Request - The changes in the request cannot be
applied to the job template
+ content:
+ application/vnd.gravitino.v1+json:
+ schema:
+ $ref: "./openapi.yaml#/components/schemas/ErrorModel"
+ examples:
+ IllegalArgumentException:
+ $ref: "#/components/examples/IllegalArgumentException"
+ "5xx":
+ $ref: "./openapi.yaml#/components/responses/ServerErrorResponse"
+
/metalakes/{metalake}/jobs/runs:
parameters:
- $ref: "./openapi.yaml#/components/parameters/metalake"
@@ -368,103 +416,216 @@ components:
$ref: "./openapi.yaml#/components/schemas/Audit"
SparkJobTemplate:
- type: object
- description: A job template object for Spark jobs
- required:
- - name
- - jobType
- - mainClass
- properties:
- name:
+ type: object
+ description: A job template object for Spark jobs
+ required:
+ - name
+ - jobType
+ - mainClass
+ properties:
+ name:
+ type: string
+ description: The name of the job template
+ jobType:
+ type: string
+ description: The type of the job template
+ enum:
+ - "spark"
+ comment:
+ type: string
+ description: A comment about the job template
+ nullable: true
+ executable:
+ type: string
+ description: The executable command of the job template
+ arguments:
+ type: array
+ description: The arguments of the job template
+ items:
type: string
- description: The name of the job template
- jobType:
+ nullable: true
+ environments:
+ type: object
+ description: Configured string to string map of environment
variables for the job template
+ default: { }
+ additionalProperties:
type: string
- description: The type of the job template
- enum:
- - "spark"
- comment:
+ customFields:
+ type: object
+ description: Configured string to string map of custom fields for
the job template
+ default: { }
+ additionalProperties:
type: string
- description: A comment about the job template
- nullable: true
- executable:
+ mainClass:
+ type: string
+ description: The main class of the Spark job template
+ jars:
+ type: array
+ description: The JAR files of the Spark job template
+ items:
type: string
- description: The executable command of the job template
- arguments:
- type: array
- description: The arguments of the job template
- items:
- type: string
- nullable: true
- environments:
- type: object
- description: Configured string to string map of environment
variables for the job template
- default: { }
- additionalProperties:
- type: string
- customFields:
- type: object
- description: Configured string to string map of custom fields for
the job template
- default: { }
- additionalProperties:
- type: string
- mainClass:
+ nullable: true
+ files:
+ type: array
+ description: The files of the Spark job template
+ items:
type: string
- description: The main class of the Spark job template
- jars:
- type: array
- description: The JAR files of the Spark job template
- items:
- type: string
- nullable: true
- files:
- type: array
- description: The files of the Spark job template
- items:
- type: string
- nullable: true
- archives:
- type: array
- description: The archives of the Spark job template
- items:
- type: string
- nullable: true
- configs:
- type: object
- description: Configured string to string map of Spark
configurations for the job template
- default: { }
- additionalProperties:
- type: string
- audit:
- $ref: "./openapi.yaml#/components/schemas/Audit"
+ nullable: true
+ archives:
+ type: array
+ description: The archives of the Spark job template
+ items:
+ type: string
+ nullable: true
+ configs:
+ type: object
+ description: Configured string to string map of Spark configurations
for the job template
+ default: { }
+ additionalProperties:
+ type: string
+ audit:
+ $ref: "./openapi.yaml#/components/schemas/Audit"
Job:
- type: object
- description: A job object
- required:
- - jobId
- - jobTemplateName
- - status
- - audit
- properties:
- jobId:
+ type: object
+ description: A job object
+ required:
+ - jobId
+ - jobTemplateName
+ - status
+ - audit
+ properties:
+ jobId:
+ type: string
+ description: The unique identifier of the job
+ jobTemplateName:
+ type: string
+ description: The name of the job template used to create the job
+ status:
+ type: string
+ description: The status of the job
+ enum:
+ - "queued"
+ - "started"
+ - "failed"
+ - "succeeded"
+ - "cancelling"
+ - "canceled"
+ audit:
+ $ref: "./openapi.yaml#/components/schemas/Audit"
+
+
+ TemplateUpdate:
+ oneOf:
+ - $ref: "#/components/schemas/ShellTemplateUpdate"
+ - $ref: "#/components/schemas/SparkTemplateUpdate"
+ discriminator:
+ propertyName: "@type"
+ mapping:
+ shell: "#/components/schemas/ShellTemplateUpdate"
+ spark: "#/components/schemas/SparkTemplateUpdate"
+
+ ShellTemplateUpdate:
+ type: object
+ description: A job template update object for shell jobs
+ required:
+ - "@type"
+ properties:
+ "@type":
+ type: string
+ description: The type of the job template
+ enum:
+ - "shell"
+ newExecutable:
+ type: string
+ description: The new executable command of the job template
+ nullable: true
+ newArguments:
+ type: array
+ description: The new arguments of the job template
+ items:
type: string
- description: The unique identifier of the job
- jobTemplateName:
+ nullable: true
+ newEnvironments:
+ type: object
+ description: The new configured string to string map of environment
variables for the job template
+ additionalProperties:
+ type: string
+ nullable: true
+ newCustomFields:
+ type: object
+ description: The new configured string to string map of custom
fields for the job template
+ additionalProperties:
type: string
- description: The name of the job template used to create the job
- status:
+ nullable: true
+ newScripts:
+ type: array
+ description: The new scripts of the job template
+ items:
type: string
- description: The status of the job
- enum:
- - "queued"
- - "started"
- - "failed"
- - "succeeded"
- - "cancelling"
- - "canceled"
- audit:
- $ref: "./openapi.yaml#/components/schemas/Audit"
+ nullable: true
+
+ SparkTemplateUpdate:
+ type: object
+ description: A job template update object for Spark jobs
+ required:
+ - "@type"
+ properties:
+ "@type":
+ type: string
+ description: The type of the job template
+ enum:
+ - "spark"
+ newExecutable:
+ type: string
+ description: The new executable command of the job template
+ nullable: true
+ newArguments:
+ type: array
+ description: The new arguments of the job template
+ items:
+ type: string
+ nullable: true
+ newEnvironments:
+ type: object
+ description: The new configured string to string map of environment
variables for the job template
+ additionalProperties:
+ type: string
+ nullable: true
+ newCustomFields:
+ type: object
+ description: The new configured string to string map of custom
fields for the job template
+ additionalProperties:
+ type: string
+ nullable: true
+ newClassName:
+ type: string
+ description: The new class name of the Spark job template
+ nullable: true
+ newJars:
+ type: array
+ description: The new JAR files of the Spark job template
+ items:
+ type: string
+ nullable: true
+ newFiles:
+ type: array
+ description: The new files of the Spark job template
+ items:
+ type: string
+ nullable: true
+ newArchives:
+ type: array
+ description: The new archives of the Spark job template
+ items:
+ type: string
+ nullable: true
+ newConfigs:
+ type: object
+ description: The new configured string to string map of Spark
configurations for the job template
+ additionalProperties:
+ type: string
+ nullable: true
requests:
@@ -476,6 +637,69 @@ components:
jobTemplate:
$ref: "#/components/schemas/JobTemplate"
+ JobTemplateUpdatesRequest:
+ type: object
+ required:
+ - updates
+ properties:
+ updates:
+ type: array
+ items:
+ $ref: "#/components/requests/JobTemplateUpdateRequest"
+
+ JobTemplateUpdateRequest:
+ oneOf:
+ - $ref: "#/components/requests/RenameJobTemplateRequest"
+ - $ref: "#/components/requests/UpdateJobTemplateCommentRequest"
+ - $ref: "#/components/requests/UpdateJobTemplateContentRequest"
+ discriminator:
+ propertyName: "@type"
+ mapping:
+ rename: "#/components/requests/RenameJobTemplateRequest"
+ updateComment:
"#/components/requests/UpdateJobTemplateCommentRequest"
+ updateTemplate:
"#/components/requests/UpdateJobTemplateContentRequest"
+
+ RenameJobTemplateRequest:
+ type: object
+ required:
+ - "@type"
+ - newName
+ properties:
+ "@type":
+ type: string
+ enum:
+ - "rename"
+ newName:
+ type: string
+ description: The new name of the job template
+
+ UpdateJobTemplateCommentRequest:
+ type: object
+ required:
+ - "@type"
+ - newComment
+ properties:
+ "@type":
+ type: string
+ enum:
+ - "updateComment"
+ newComment:
+ type: string
+ description: The new comment of the job template
+
+ UpdateJobTemplateContentRequest:
+ type: object
+ required:
+ - "@type"
+ - newTemplate
+ properties:
+ "@type":
+ type: string
+ enum:
+ - "updateTemplate"
+ newTemplate:
+ $ref: "#/components/schemas/TemplateUpdate"
+
JobRunRequest:
type: object
required:
@@ -621,6 +845,37 @@ components:
}
}
+ JobTemplateUpdatesRequest:
+ value: {
+ "updates": [
+ {
+ "@type": "rename",
+ "newName": "new_test_run_get"
+ },
+ {
+ "@type": "updateComment",
+ "newComment": "Updated comment for the job template"
+ },
+ {
+ "@type": "updateTemplate",
+ "newTemplate": {
+ "@type": "shell",
+ "newExecutable":
"/var/folders/90/v1d9hxsd6pj8m0jnn6f22tkr0000gn/T/tmpy65fiugc/updated-test-job.sh",
+ "newArguments": ["{{new_arg1}}", "{{new_arg2}}"],
+ "newEnvironments": {
+ "NEW_ENV_VAR": "{{new_env_var}}"
+ },
+ "newCustomFields": {
+ "field1": "value1"
+ },
+ "newScripts": [
+
"/var/folders/90/v1d9hxsd6pj8m0jnn6f22tkr0000gn/T/tmpy65fiugc/updated-common.sh"
+ ]
+ }
+ }
+ ]
+ }
+
JobRunRequest:
value: {
"jobTemplateName": "test_run_get",
@@ -724,3 +979,14 @@ components:
"..."
]
}
+
+ IllegalArgumentException:
+ value: {
+ "code": 1001,
+ "type": "IllegalArgumentException",
+ "message": "Failed to operate job template(s) [my_job] operation
[UPDATE], reason [IllegalArgumentException]",
+ "stack": [
+ "java.lang.IllegalArgumentException: Invalid argument xxx",
+ "..."
+ ]
+ }