From 10b408db75fe4fab397d6437f8f5e471e3d88dea Mon Sep 17 00:00:00 2001 From: Pere Miquel Brull Date: Tue, 29 Apr 2025 08:19:13 +0200 Subject: [PATCH] FIX #16284 - Toggle if we want to raise workflow errors (#20969) * FIX #16284 - Toggle if we want to raise workflow errors * schema * schema * move prop * fix * move prop * improve error handling * Update openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/IngestionPipelineRepository.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/IngestionPipelineRepository.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add the `Raise on Error` option to the ingestion schedule step * Revert "Update openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/IngestionPipelineRepository.java" This reverts commit 985b73513a59695c6bb39ad41c2d273bbf4e5d22. * Update the tests * Fix sonar issue --------- Co-authored-by: Aniket Katkar Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- ingestion/src/metadata/cli/classify.py | 6 +- ingestion/src/metadata/cli/common.py | 26 ++++++ ingestion/src/metadata/cli/dataquality.py | 6 +- ingestion/src/metadata/cli/ingest.py | 6 +- ingestion/src/metadata/cli/profile.py | 6 +- ingestion/src/metadata/cli/usage.py | 6 +- ingestion/src/metadata/workflow/base.py | 9 ++- .../workflow/workflow_status_mixin.py | 8 +- .../workflows/ingestion/application.py | 11 ++- .../ingestion/auto_classification.py | 16 ++-- .../workflows/ingestion/common.py | 25 ++++-- .../workflows/ingestion/dbt.py | 2 +- .../workflows/ingestion/profiler.py | 16 ++-- .../workflows/ingestion/test_suite.py | 16 ++-- .../workflows/ingestion/usage.py | 11 ++- .../jdbi3/IngestionPipelineRepository.java | 7 ++ .../IngestionPipelineMapper.java | 1 + .../createIngestionPipeline.json | 5 ++ .../ingestionPipelines/ingestionPipeline.json | 5 ++ .../schema/metadataIngestion/workflow.json | 5 ++ .../entity/ingestion/ServiceBaseClass.ts | 12 +++ .../en-US/Dashboard/workflows/metadata.md | 5 ++ .../locales/en-US/Database/workflows/dbt.md | 6 ++ .../en-US/Database/workflows/lineage.md | 6 ++ .../en-US/Database/workflows/metadata.md | 6 ++ .../en-US/Database/workflows/profiler.md | 6 ++ .../locales/en-US/Database/workflows/usage.md | 6 ++ .../en-US/Messaging/workflows/metadata.md | 6 ++ .../en-US/Metadata/workflows/dataInsight.md | 6 ++ .../workflows/elasticSearchReindex.md | 6 ++ .../en-US/Metadata/workflows/metadata.md | 6 ++ .../en-US/MlModel/workflows/metadata.md | 6 ++ .../en-US/Pipeline/workflows/metadata.md | 6 ++ .../en-US/Storage/workflows/metadata.md | 6 ++ .../AddDataQualityTest.interface.ts | 1 + .../AddDataQualityTest/TestSuiteIngestion.tsx | 3 + .../components/AddTestSuitePipeline.test.tsx | 4 + .../components/AddTestSuitePipeline.tsx | 79 +++++++++++-------- .../AddIngestion/AddIngestion.component.tsx | 55 +++++++++---- .../AddIngestion/AddIngestion.test.tsx | 5 ++ .../Steps/ScheduleInterval.interface.ts | 1 + .../AddIngestion/Steps/ScheduleInterval.tsx | 2 +- .../ui/src/constants/Ingestions.constant.ts | 8 +- .../createIngestionPipeline.ts | 8 ++ .../ingestionPipelines/ingestionPipeline.ts | 8 ++ .../generated/metadataIngestion/workflow.ts | 8 ++ .../ui/src/interface/service.interface.ts | 1 + .../ui/src/locale/languages/de-de.json | 1 + .../ui/src/locale/languages/en-us.json | 1 + .../ui/src/locale/languages/es-es.json | 1 + .../ui/src/locale/languages/fr-fr.json | 1 + .../ui/src/locale/languages/gl-es.json | 1 + .../ui/src/locale/languages/he-he.json | 1 + .../ui/src/locale/languages/ja-jp.json | 1 + .../ui/src/locale/languages/ko-kr.json | 1 + .../ui/src/locale/languages/mr-in.json | 1 + .../ui/src/locale/languages/nl-nl.json | 1 + .../ui/src/locale/languages/pr-pr.json | 1 + .../ui/src/locale/languages/pt-br.json | 1 + .../ui/src/locale/languages/pt-pt.json | 1 + .../ui/src/locale/languages/ru-ru.json | 1 + .../ui/src/locale/languages/th-th.json | 1 + .../ui/src/locale/languages/zh-cn.json | 1 + .../resources/ui/src/utils/SchedularUtils.tsx | 20 +++++ 64 files changed, 380 insertions(+), 121 deletions(-) create mode 100644 ingestion/src/metadata/cli/common.py diff --git a/ingestion/src/metadata/cli/classify.py b/ingestion/src/metadata/cli/classify.py index ce3e110c600..b0fd3cdb22f 100644 --- a/ingestion/src/metadata/cli/classify.py +++ b/ingestion/src/metadata/cli/classify.py @@ -16,6 +16,7 @@ import sys import traceback from pathlib import Path +from metadata.cli.common import execute_workflow from metadata.config.common import load_config_file from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( PipelineType, @@ -46,7 +47,4 @@ def run_classification(config_path: Path) -> None: ) sys.exit(1) - workflow.execute() - workflow.stop() - workflow.print_status() - workflow.raise_from_status() + execute_workflow(workflow=workflow, config_dict=config_dict) diff --git a/ingestion/src/metadata/cli/common.py b/ingestion/src/metadata/cli/common.py new file mode 100644 index 00000000000..1e07ebde2ba --- /dev/null +++ b/ingestion/src/metadata/cli/common.py @@ -0,0 +1,26 @@ +# Copyright 2025 Collate +# Licensed under the Collate Community License, Version 1.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# https://github.com/open-metadata/OpenMetadata/blob/main/ingestion/LICENSE +# 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. + +""" +Handle workflow execution +""" +from typing import Any, Dict + +from metadata.workflow.base import BaseWorkflow + + +def execute_workflow(workflow: BaseWorkflow, config_dict: Dict[str, Any]) -> None: + """Execute the workflow and raise if needed""" + workflow.execute() + workflow.print_status() + workflow.stop() + if config_dict.get("workflowConfig", {}).get("raiseOnError", True): + workflow.raise_from_status() diff --git a/ingestion/src/metadata/cli/dataquality.py b/ingestion/src/metadata/cli/dataquality.py index 2b3d2937069..6c4d9866ed0 100644 --- a/ingestion/src/metadata/cli/dataquality.py +++ b/ingestion/src/metadata/cli/dataquality.py @@ -16,6 +16,7 @@ import sys import traceback from pathlib import Path +from metadata.cli.common import execute_workflow from metadata.config.common import load_config_file from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( PipelineType, @@ -48,7 +49,4 @@ def run_test(config_path: Path) -> None: ) sys.exit(1) - workflow.execute() - workflow.stop() - workflow.print_status() - workflow.raise_from_status() + execute_workflow(workflow=workflow, config_dict=workflow_config_dict) diff --git a/ingestion/src/metadata/cli/ingest.py b/ingestion/src/metadata/cli/ingest.py index e33a5bf58ec..ddc92c6b9ea 100644 --- a/ingestion/src/metadata/cli/ingest.py +++ b/ingestion/src/metadata/cli/ingest.py @@ -16,6 +16,7 @@ import sys import traceback from pathlib import Path +from metadata.cli.common import execute_workflow from metadata.config.common import load_config_file from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( PipelineType, @@ -46,7 +47,4 @@ def run_ingest(config_path: Path) -> None: ) sys.exit(1) - workflow.execute() - workflow.stop() - workflow.print_status() - workflow.raise_from_status() + execute_workflow(workflow=workflow, config_dict=config_dict) diff --git a/ingestion/src/metadata/cli/profile.py b/ingestion/src/metadata/cli/profile.py index c967a7d6f5a..5ccfc4084f6 100644 --- a/ingestion/src/metadata/cli/profile.py +++ b/ingestion/src/metadata/cli/profile.py @@ -16,6 +16,7 @@ import sys import traceback from pathlib import Path +from metadata.cli.common import execute_workflow from metadata.config.common import load_config_file from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( PipelineType, @@ -48,7 +49,4 @@ def run_profiler(config_path: Path) -> None: ) sys.exit(1) - workflow.execute() - workflow.stop() - workflow.print_status() - workflow.raise_from_status() + execute_workflow(workflow=workflow, config_dict=workflow_config_dict) diff --git a/ingestion/src/metadata/cli/usage.py b/ingestion/src/metadata/cli/usage.py index 92c6b665cdf..2447c37eaba 100644 --- a/ingestion/src/metadata/cli/usage.py +++ b/ingestion/src/metadata/cli/usage.py @@ -16,6 +16,7 @@ import sys import traceback from pathlib import Path +from metadata.cli.common import execute_workflow from metadata.config.common import load_config_file from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( PipelineType, @@ -44,7 +45,4 @@ def run_usage(config_path: Path) -> None: WorkflowInitErrorHandler.print_init_error(exc, config_dict, PipelineType.usage) sys.exit(1) - workflow.execute() - workflow.stop() - workflow.print_status() - workflow.raise_from_status() + execute_workflow(workflow=workflow, config_dict=config_dict) diff --git a/ingestion/src/metadata/workflow/base.py b/ingestion/src/metadata/workflow/base.py index 4a33dc8932d..17f7e82730a 100644 --- a/ingestion/src/metadata/workflow/base.py +++ b/ingestion/src/metadata/workflow/base.py @@ -219,7 +219,14 @@ class BaseWorkflow(ABC, WorkflowStatusMixin): if self.workflow_config.successThreshold <= self.calculate_success() < 100: pipeline_state = PipelineState.partialSuccess - # Any unhandled exception breaking the workflow should update the status + # If there's any steps that should raise a failed status, + # raise it here to set the pipeline status as failed + try: + self.raise_from_status_internal() + except WorkflowExecutionError: + pipeline_state = PipelineState.failed + + # Any unhandled exception should blow up the execution except Exception as err: pipeline_state = PipelineState.failed raise err diff --git a/ingestion/src/metadata/workflow/workflow_status_mixin.py b/ingestion/src/metadata/workflow/workflow_status_mixin.py index cda4347c7d1..d7225dde288 100644 --- a/ingestion/src/metadata/workflow/workflow_status_mixin.py +++ b/ingestion/src/metadata/workflow/workflow_status_mixin.py @@ -17,7 +17,6 @@ from datetime import datetime from enum import Enum from typing import Optional, Tuple -from metadata.config.common import WorkflowExecutionError from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( IngestionPipeline, PipelineState, @@ -129,13 +128,8 @@ class WorkflowStatusMixin: def raise_from_status(self, raise_warnings=False): """ Method to raise error if failed execution - and updating Ingestion Pipeline Status """ - try: - self.raise_from_status_internal(raise_warnings) - except WorkflowExecutionError as err: - self.set_ingestion_pipeline_status(PipelineState.failed) - raise err + self.raise_from_status_internal(raise_warnings) def result_status(self) -> WorkflowResultStatus: """ diff --git a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/application.py b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/application.py index d08dbb0b007..6ba8b1fa7dd 100644 --- a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/application.py +++ b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/application.py @@ -18,6 +18,7 @@ from openmetadata_managed_apis.utils.logger import set_operator_logger from openmetadata_managed_apis.workflows.ingestion.common import ( build_dag, build_workflow_config_property, + execute_workflow, ) from metadata.generated.schema.entity.applications.configuration.applicationConfig import ( @@ -36,7 +37,9 @@ from metadata.generated.schema.metadataIngestion.applicationPipeline import ( from metadata.workflow.application import ApplicationWorkflow -def application_workflow(workflow_config: OpenMetadataApplicationConfig): +def application_workflow( + workflow_config: OpenMetadataApplicationConfig, +): """ Task that creates and runs the ingestion workflow. @@ -52,11 +55,7 @@ def application_workflow(workflow_config: OpenMetadataApplicationConfig): workflow_config.model_dump_json(exclude_defaults=False, mask_secrets=False) ) workflow = ApplicationWorkflow.create(config) - - workflow.execute() - workflow.raise_from_status() - workflow.print_status() - workflow.stop() + execute_workflow(workflow, workflow_config) def build_application_workflow_config( diff --git a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/auto_classification.py b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/auto_classification.py index 5d4916dbab0..b14b3e84720 100644 --- a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/auto_classification.py +++ b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/auto_classification.py @@ -15,7 +15,11 @@ import json from airflow import DAG from openmetadata_managed_apis.utils.logger import set_operator_logger -from openmetadata_managed_apis.workflows.ingestion.common import build_dag, build_source +from openmetadata_managed_apis.workflows.ingestion.common import ( + build_dag, + build_source, + execute_workflow, +) from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( IngestionPipeline, @@ -30,7 +34,9 @@ from metadata.generated.schema.metadataIngestion.workflow import ( from metadata.workflow.classification import AutoClassificationWorkflow -def auto_classification_workflow(workflow_config: OpenMetadataWorkflowConfig): +def auto_classification_workflow( + workflow_config: OpenMetadataWorkflowConfig, +): """ Task that creates and runs the auto classification workflow. @@ -46,11 +52,7 @@ def auto_classification_workflow(workflow_config: OpenMetadataWorkflowConfig): workflow_config.model_dump_json(exclude_defaults=False, mask_secrets=False) ) workflow = AutoClassificationWorkflow.create(config) - - workflow.execute() - workflow.raise_from_status() - workflow.print_status() - workflow.stop() + execute_workflow(workflow, workflow_config) def build_auto_classification_workflow_config( diff --git a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/common.py b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/common.py index 3a8daf95a66..8f550e8055f 100644 --- a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/common.py +++ b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/common.py @@ -37,6 +37,7 @@ from metadata.generated.schema.metadataIngestion.application import ( from metadata.generated.schema.type.basic import Timestamp, Uuid from metadata.ingestion.ometa.ometa_api import OpenMetadata from metadata.utils import fqn +from metadata.workflow.base import BaseWorkflow # pylint: disable=ungrouped-imports try: @@ -192,6 +193,19 @@ def build_source(ingestion_pipeline: IngestionPipeline) -> WorkflowSource: ) +def execute_workflow( + workflow: BaseWorkflow, workflow_config: OpenMetadataWorkflowConfig +) -> None: + """ + Execute the workflow and handle the status + """ + workflow.execute() + workflow.print_status() + workflow.stop() + if workflow_config.workflowConfig.raiseOnError: + workflow.raise_from_status() + + def metadata_ingestion_workflow(workflow_config: OpenMetadataWorkflowConfig): """ Task that creates and runs the ingestion workflow. @@ -208,11 +222,7 @@ def metadata_ingestion_workflow(workflow_config: OpenMetadataWorkflowConfig): workflow_config.model_dump_json(exclude_defaults=False, mask_secrets=False) ) workflow = MetadataWorkflow.create(config) - - workflow.execute() - workflow.raise_from_status() - workflow.print_status() - workflow.stop() + execute_workflow(workflow, workflow_config) def build_workflow_config_property( @@ -225,6 +235,7 @@ def build_workflow_config_property( """ return WorkflowConfig( loggerLevel=ingestion_pipeline.loggerLevel or LogLevels.INFO, + raiseOnError=ingestion_pipeline.raiseOnError, openMetadataServerConfig=ingestion_pipeline.openMetadataServerConnection, ) @@ -371,7 +382,9 @@ def build_dag( CustomPythonOperator( task_id=task_name, python_callable=workflow_fn, - op_kwargs={"workflow_config": workflow_config}, + op_kwargs={ + "workflow_config": workflow_config, + }, # There's no need to retry if we have had an error. Wait until the next schedule or manual rerun. retries=ingestion_pipeline.airflowConfig.retries or 0, # each DAG will call its own OpenMetadataWorkflowConfig diff --git a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/dbt.py b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/dbt.py index 6e4ce93d01c..6a71c1ccff3 100644 --- a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/dbt.py +++ b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/dbt.py @@ -42,7 +42,7 @@ def build_dbt_workflow_config( """ source = build_source(ingestion_pipeline) - source.type = f"dbt" # Mark the source as dbt + source.type = "dbt" # Mark the source as dbt workflow_config = OpenMetadataWorkflowConfig( source=source, diff --git a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/profiler.py b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/profiler.py index 36dd9df0284..0141b3bad20 100644 --- a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/profiler.py +++ b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/profiler.py @@ -15,7 +15,11 @@ import json from airflow import DAG from openmetadata_managed_apis.utils.logger import set_operator_logger -from openmetadata_managed_apis.workflows.ingestion.common import build_dag, build_source +from openmetadata_managed_apis.workflows.ingestion.common import ( + build_dag, + build_source, + execute_workflow, +) from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( IngestionPipeline, @@ -30,7 +34,9 @@ from metadata.generated.schema.metadataIngestion.workflow import ( from metadata.workflow.profiler import ProfilerWorkflow -def profiler_workflow(workflow_config: OpenMetadataWorkflowConfig): +def profiler_workflow( + workflow_config: OpenMetadataWorkflowConfig, +): """ Task that creates and runs the profiler workflow. @@ -46,11 +52,7 @@ def profiler_workflow(workflow_config: OpenMetadataWorkflowConfig): workflow_config.model_dump_json(exclude_defaults=False, mask_secrets=False) ) workflow = ProfilerWorkflow.create(config) - - workflow.execute() - workflow.raise_from_status() - workflow.print_status() - workflow.stop() + execute_workflow(workflow, workflow_config) def build_profiler_workflow_config( diff --git a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/test_suite.py b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/test_suite.py index 7c704bc40ad..0b9ea399c64 100644 --- a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/test_suite.py +++ b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/test_suite.py @@ -15,7 +15,11 @@ import json from airflow import DAG from openmetadata_managed_apis.utils.logger import set_operator_logger -from openmetadata_managed_apis.workflows.ingestion.common import build_dag, build_source +from openmetadata_managed_apis.workflows.ingestion.common import ( + build_dag, + build_source, + execute_workflow, +) from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( IngestionPipeline, @@ -30,7 +34,9 @@ from metadata.generated.schema.metadataIngestion.workflow import ( from metadata.workflow.data_quality import TestSuiteWorkflow -def test_suite_workflow(workflow_config: OpenMetadataWorkflowConfig): +def test_suite_workflow( + workflow_config: OpenMetadataWorkflowConfig, +): """ Task that creates and runs the test suite workflow. @@ -46,11 +52,7 @@ def test_suite_workflow(workflow_config: OpenMetadataWorkflowConfig): workflow_config.model_dump_json(exclude_defaults=False, mask_secrets=False) ) workflow = TestSuiteWorkflow.create(config) - - workflow.execute() - workflow.raise_from_status() - workflow.print_status() - workflow.stop() + execute_workflow(workflow, workflow_config) def build_test_suite_workflow_config( diff --git a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/usage.py b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/usage.py index e2302d1a131..b42cd3caad9 100644 --- a/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/usage.py +++ b/openmetadata-airflow-apis/openmetadata_managed_apis/workflows/ingestion/usage.py @@ -20,6 +20,7 @@ from openmetadata_managed_apis.workflows.ingestion.common import ( build_dag, build_source, build_workflow_config_property, + execute_workflow, ) from metadata.generated.schema.entity.services.ingestionPipelines.ingestionPipeline import ( @@ -34,7 +35,9 @@ from metadata.generated.schema.metadataIngestion.workflow import ( from metadata.workflow.usage import UsageWorkflow -def usage_workflow(workflow_config: OpenMetadataWorkflowConfig): +def usage_workflow( + workflow_config: OpenMetadataWorkflowConfig, +): """ Task that creates and runs the ingestion workflow. @@ -50,11 +53,7 @@ def usage_workflow(workflow_config: OpenMetadataWorkflowConfig): workflow_config.model_dump_json(exclude_defaults=False, mask_secrets=False) ) workflow = UsageWorkflow.create(config) - - workflow.execute() - workflow.raise_from_status() - workflow.print_status() - workflow.stop() + execute_workflow(workflow, workflow_config) def build_usage_config_from_file( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/IngestionPipelineRepository.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/IngestionPipelineRepository.java index ea75f2a75ea..5a0f1666738 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/IngestionPipelineRepository.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/IngestionPipelineRepository.java @@ -337,6 +337,7 @@ public class IngestionPipelineRepository extends EntityRepository = ({ testCases, name: ingestionPipeline?.displayName, selectAllTestCases: !isEmpty(ingestionPipeline) && isUndefined(testCases), + raiseOnError: ingestionPipeline?.raiseOnError ?? true, }; }, [ingestionPipeline]); @@ -173,6 +174,7 @@ const TestSuiteIngestion: React.FC = ({ name: generateUUID(), loggerLevel: data.enableDebugLog ? LogLevels.Debug : LogLevels.Info, pipelineType: PipelineType.TestSuite, + raiseOnError: data.raiseOnError ?? true, service: { id: testSuite.id ?? '', type: camelCase(PipelineType.TestSuite), @@ -210,6 +212,7 @@ const TestSuiteIngestion: React.FC = ({ ...ingestionPipeline?.airflowConfig, scheduleInterval: data.cron, }, + raiseOnError: data.raiseOnError ?? true, loggerLevel: data.enableDebugLog ? LogLevels.Debug : LogLevels.Info, sourceConfig: { ...ingestionPipeline?.sourceConfig, diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/AddTestSuitePipeline.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/AddTestSuitePipeline.test.tsx index 310692ccad4..1d813f04da9 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/AddTestSuitePipeline.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/AddTestSuitePipeline.test.tsx @@ -50,6 +50,10 @@ jest.mock('react-router-dom', () => ({ useHistory: jest.fn().mockImplementation(() => mockUseHistory), })); +jest.mock('../../../../utils/SchedularUtils', () => ({ + getRaiseOnErrorFormField: jest.fn().mockReturnValue({}), +})); + const mockProps: AddTestSuitePipelineProps = { isLoading: false, onSubmit: jest.fn(), diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/AddTestSuitePipeline.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/AddTestSuitePipeline.tsx index dd6030292d2..0d1f392e2af 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/AddTestSuitePipeline.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/AddDataQualityTest/components/AddTestSuitePipeline.tsx @@ -27,6 +27,7 @@ import { FormItemLayout, } from '../../../../interface/FormUtils.interface'; import { generateFormFields } from '../../../../utils/formUtils'; +import { getRaiseOnErrorFormField } from '../../../../utils/SchedularUtils'; import { escapeESReservedCharacters } from '../../../../utils/StringsUtils'; import ScheduleInterval from '../../../Settings/Services/AddIngestion/Steps/ScheduleInterval'; import { WorkflowExtraConfig } from '../../../Settings/Services/AddIngestion/Steps/ScheduleInterval.interface'; @@ -105,8 +106,14 @@ const AddTestSuitePipeline = ({ const onFinish = ( values: WorkflowExtraConfig & TestSuiteIngestionDataType ) => { - const { cron, enableDebugLog, testCases, name, selectAllTestCases } = - values; + const { + cron, + enableDebugLog, + testCases, + name, + selectAllTestCases, + raiseOnError, + } = values; onSubmit({ cron, enableDebugLog, @@ -115,6 +122,7 @@ const AddTestSuitePipeline = ({ testCases: testCases?.map((testCase: TestCase | string) => isString(testCase) ? testCase : testCase.name ), + raiseOnError, }); }; @@ -130,6 +138,8 @@ const AddTestSuitePipeline = ({ } }; + const raiseOnErrorFormField = useMemo(() => getRaiseOnErrorFormField(), []); + return ( - - {generateFormFields(testCaseFormFields)} - {!selectAllTestCases && ( - - - - - - )} - + {generateFormFields([raiseOnErrorFormField])} + + + {generateFormFields(testCaseFormFields)} + {!selectAllTestCases && ( + + + + + + )} + + ); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.component.tsx index 02317f43857..44134942829 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.component.tsx @@ -11,7 +11,7 @@ * limitations under the License. */ -import { Form, Input, Typography } from 'antd'; +import { Col, Form, Input, Typography } from 'antd'; import { isEmpty, isUndefined, omit, trim } from 'lodash'; import React, { useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -29,12 +29,16 @@ import { IngestionPipeline } from '../../../../generated/entity/services/ingesti import { useApplicationStore } from '../../../../hooks/useApplicationStore'; import { useFqn } from '../../../../hooks/useFqn'; import { IngestionWorkflowData } from '../../../../interface/service.interface'; +import { generateFormFields } from '../../../../utils/formUtils'; import { getDefaultFilterPropertyValues, getSuccessMessage, } from '../../../../utils/IngestionUtils'; import { cleanWorkFlowData } from '../../../../utils/IngestionWorkflowUtils'; -import { getScheduleOptionsFromSchedules } from '../../../../utils/SchedularUtils'; +import { + getRaiseOnErrorFormField, + getScheduleOptionsFromSchedules, +} from '../../../../utils/SchedularUtils'; import { getIngestionName } from '../../../../utils/ServiceUtils'; import { generateUUID } from '../../../../utils/StringsUtils'; import SuccessScreen from '../../../common/SuccessScreen/SuccessScreen'; @@ -108,6 +112,7 @@ const AddIngestion = ({ displayName: data?.displayName ?? getIngestionName(serviceData.name, pipelineType), enableDebugLog: data?.loggerLevel === LogLevels.Debug, + raiseOnError: data?.raiseOnError ?? true, }) ); @@ -167,6 +172,7 @@ const AddIngestion = ({ name = '', enableDebugLog, displayName, + raiseOnError, ...rest } = workflowData ?? {}; const ingestionName = trim(name); @@ -183,6 +189,7 @@ const AddIngestion = ({ startDate: date, retries: extraData.retries, }, + raiseOnError: extraData.raiseOnError ?? true, loggerLevel: enableDebugLog ? LogLevels.Debug : LogLevels.Info, name: ingestionName, displayName: displayName, @@ -234,6 +241,7 @@ const AddIngestion = ({ scheduleInterval: extraData.cron, retries: extraData.retries, }, + raiseOnError: extraData.raiseOnError ?? true, displayName: workflowData?.displayName, loggerLevel: workflowData?.enableDebugLog ? LogLevels.Debug @@ -242,8 +250,12 @@ const AddIngestion = ({ config: { // clean the data to remove empty fields ...cleanWorkFlowData( - omit(workflowData, ['name', 'enableDebugLog', 'displayName']) ?? - {} + omit(workflowData, [ + 'name', + 'enableDebugLog', + 'displayName', + 'raiseOnError', + ]) ?? {} ), }, }, @@ -286,6 +298,11 @@ const AddIngestion = ({ } }; + const raiseOnErrorFormField = useMemo( + () => getRaiseOnErrorFormField(onFocus), + [onFocus] + ); + return (
@@ -324,22 +341,28 @@ const AddIngestion = ({ defaultSchedule={DEFAULT_SCHEDULE_CRON_DAILY} disabled={pipelineType === PipelineType.DataInsight} includePeriodOptions={periodOptions} - initialData={{ cron: data?.airflowConfig.scheduleInterval }} + initialData={{ + cron: data?.airflowConfig.scheduleInterval, + raiseOnError: data?.raiseOnError ?? true, + }} isEditMode={isEditMode} status={saveState} onBack={() => handlePrev(1)} onDeploy={handleScheduleIntervalDeployClick}> - - onFocus('root/retries')} - /> - + + + onFocus('root/retries')} + /> + + + {generateFormFields([raiseOnErrorFormField])} )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.test.tsx index a0d32f0d377..91a3adcdcb2 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/AddIngestion.test.tsx @@ -61,6 +61,11 @@ jest.mock('../Ingestion/IngestionWorkflowForm/IngestionWorkflowForm', () => { return jest.fn().mockImplementation(() =>
Ingestion workflow form
); }); +jest.mock('../../../../utils/SchedularUtils', () => ({ + getScheduleOptionsFromSchedules: jest.fn().mockReturnValue([]), + getRaiseOnErrorFormField: jest.fn().mockReturnValue({}), +})); + describe('Test AddIngestion component', () => { it('AddIngestion component should render', async () => { const { container } = render(); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/Steps/ScheduleInterval.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/Steps/ScheduleInterval.interface.ts index 8a893a814d9..d9e0437df36 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/Steps/ScheduleInterval.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/Steps/ScheduleInterval.interface.ts @@ -49,6 +49,7 @@ export interface WorkflowExtraConfig { export interface IngestionExtraConfig { retries?: number; + raiseOnError?: boolean; } export interface Combination { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/Steps/ScheduleInterval.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/Steps/ScheduleInterval.tsx index d586974b506..c3ccc7c5d91 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/Steps/ScheduleInterval.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/AddIngestion/Steps/ScheduleInterval.tsx @@ -394,7 +394,7 @@ const ScheduleInterval = ({ {generateFormFields(formFields)} )} - {children && {children}} + {children} {showActionButtons && ( diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/Ingestions.constant.ts b/openmetadata-ui/src/main/resources/ui/src/constants/Ingestions.constant.ts index 04423cda3e3..7c89bee306f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/Ingestions.constant.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/Ingestions.constant.ts @@ -15,14 +15,16 @@ import i18next from 'i18next'; import { StepperStepType } from 'Models'; import { PipelineType } from '../generated/entity/services/ingestionPipelines/ingestionPipeline'; +const { t } = i18next; + export const STEPS_FOR_ADD_INGESTION: Array = [ { - name: i18next.t('label.configure-entity', { - entity: i18next.t('label.ingestion'), + name: t('label.configure-entity', { + entity: t('label.ingestion'), }), step: 1, }, - { name: i18next.t('label.schedule-interval'), step: 2 }, + { name: t('label.schedule-interval'), step: 2 }, ]; export const INGESTION_ACTION_TYPE = { diff --git a/openmetadata-ui/src/main/resources/ui/src/generated/api/services/ingestionPipelines/createIngestionPipeline.ts b/openmetadata-ui/src/main/resources/ui/src/generated/api/services/ingestionPipelines/createIngestionPipeline.ts index d1db9362b2b..72bfe115083 100644 --- a/openmetadata-ui/src/main/resources/ui/src/generated/api/services/ingestionPipelines/createIngestionPipeline.ts +++ b/openmetadata-ui/src/main/resources/ui/src/generated/api/services/ingestionPipelines/createIngestionPipeline.ts @@ -40,6 +40,10 @@ export interface CreateIngestionPipeline { */ owners?: EntityReference[]; pipelineType: PipelineType; + /** + * Control if we want to flag the workflow as failed if we encounter any processing errors. + */ + raiseOnError?: boolean; /** * Link to the service for which ingestion pipeline is ingesting the metadata. */ @@ -687,6 +691,10 @@ export interface Pipeline { * like endpoints, etc., with that collection will be deleted */ markDeletedApiCollections?: boolean; + /** + * Optional value of the ingestion runner name responsible for running the workflow + */ + ingestionRunner?: string; /** * List of operations to be performed on the service */ diff --git a/openmetadata-ui/src/main/resources/ui/src/generated/entity/services/ingestionPipelines/ingestionPipeline.ts b/openmetadata-ui/src/main/resources/ui/src/generated/entity/services/ingestionPipelines/ingestionPipeline.ts index 5c65ad5f2a4..c5ff2414b22 100644 --- a/openmetadata-ui/src/main/resources/ui/src/generated/entity/services/ingestionPipelines/ingestionPipeline.ts +++ b/openmetadata-ui/src/main/resources/ui/src/generated/entity/services/ingestionPipelines/ingestionPipeline.ts @@ -88,6 +88,10 @@ export interface IngestionPipeline { pipelineStatuses?: PipelineStatus; pipelineType: PipelineType; provider?: ProviderType; + /** + * Control if we want to flag the workflow as failed if we encounter any processing errors. + */ + raiseOnError?: boolean; /** * Link to the service (such as database, messaging, storage services, etc. for which this * ingestion pipeline ingests the metadata from. @@ -1247,6 +1251,10 @@ export interface Pipeline { * like endpoints, etc., with that collection will be deleted */ markDeletedApiCollections?: boolean; + /** + * Optional value of the ingestion runner name responsible for running the workflow + */ + ingestionRunner?: string; /** * List of operations to be performed on the service */ diff --git a/openmetadata-ui/src/main/resources/ui/src/generated/metadataIngestion/workflow.ts b/openmetadata-ui/src/main/resources/ui/src/generated/metadataIngestion/workflow.ts index d32d944c04e..b4dee2013b8 100644 --- a/openmetadata-ui/src/main/resources/ui/src/generated/metadataIngestion/workflow.ts +++ b/openmetadata-ui/src/main/resources/ui/src/generated/metadataIngestion/workflow.ts @@ -4332,6 +4332,10 @@ export interface Pipeline { * like endpoints, etc., with that collection will be deleted */ markDeletedApiCollections?: boolean; + /** + * Optional value of the ingestion runner name responsible for running the workflow + */ + ingestionRunner?: string; /** * List of operations to be performed on the service */ @@ -5412,6 +5416,10 @@ export interface WorkflowConfig { config?: { [key: string]: any }; loggerLevel?: LogLevels; openMetadataServerConfig: OpenMetadataConnection; + /** + * Control if we want to flag the workflow as failed if we encounter any processing errors. + */ + raiseOnError?: boolean; /** * The percentage of successfully processed records that must be achieved for the pipeline * to be considered successful. Otherwise, the pipeline will be marked as failed. diff --git a/openmetadata-ui/src/main/resources/ui/src/interface/service.interface.ts b/openmetadata-ui/src/main/resources/ui/src/interface/service.interface.ts index b1e784e2c6b..1ab566f833e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/interface/service.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/interface/service.interface.ts @@ -122,6 +122,7 @@ export type IngestionWorkflowData = Pipeline & { name: string; enableDebugLog?: boolean; displayName?: string; + raiseOnError?: boolean; }; export interface IngestionWorkflowFormProps { diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json index 7b2a6cb9232..1b6baef3754 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/de-de.json @@ -1054,6 +1054,7 @@ "query-plural": "Abfragen", "query-used-in": "Verwendete Abfragen in", "queued": "Eingereiht", + "raise-on-error": "Fehler beim Ausführen anzeigen", "range": "Bereich", "range-condition": "Bereichsbedingung", "re-assign": "Reassign", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json index 1757da0d384..73d9d3d7438 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json @@ -1054,6 +1054,7 @@ "query-plural": "Queries", "query-used-in": "Query Used In", "queued": "Queued", + "raise-on-error": "Raise on Error", "range": "Range", "range-condition": "Range Condition", "re-assign": "Reassign", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json index f250a23dbcb..b535a286ffa 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/es-es.json @@ -1054,6 +1054,7 @@ "query-plural": "Consultas", "query-used-in": "Consulta usada en", "queued": "Queued", + "raise-on-error": "Mostrar error al ejecutar", "range": "Rango", "range-condition": "Condición de Rango", "re-assign": "Reasignar", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json index 2b33d9b493b..60f6934b24f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/fr-fr.json @@ -1054,6 +1054,7 @@ "query-plural": "Requêtes", "query-used-in": "Requêtes Utilisées dans", "queued": "Queued", + "raise-on-error": "Afficher l'erreur lors de l'exécution", "range": "Amplitude", "range-condition": "Condition de Plage", "re-assign": "Réaffecter", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json index 6669e4fe8f1..00b15158141 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/gl-es.json @@ -1054,6 +1054,7 @@ "query-plural": "Consultas", "query-used-in": "Consulta utilizada en", "queued": "Queued", + "raise-on-error": "Mostrar erro ao executar", "range": "Intervalo", "range-condition": "Condición de Rango", "re-assign": "Reasignar", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json index 4792cfcf616..926f63f5cfa 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/he-he.json @@ -1054,6 +1054,7 @@ "query-plural": "שאילתות", "query-used-in": "שאילתה שמשמשת ב", "queued": "Queued", + "raise-on-error": "הצג שגיאה בעת ביצוע", "range": "טווח", "range-condition": "תנאי טווח", "re-assign": "Reassign", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json index 08061c2d71e..50045fc575c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ja-jp.json @@ -1054,6 +1054,7 @@ "query-plural": "クエリ", "query-used-in": "Query Used In", "queued": "Queued", + "raise-on-error": "エラー時に表示", "range": "Range", "range-condition": "範囲条件", "re-assign": "Reassign", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json index 67c680a8833..245eaac5b79 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ko-kr.json @@ -1054,6 +1054,7 @@ "query-plural": "쿼리들", "query-used-in": "사용된 쿼리", "queued": "Queued", + "raise-on-error": "오류 발생 시 표시", "range": "범위", "range-condition": "Range Condition", "re-assign": "재할당", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json index 0b84a927cf0..eb72adf1abb 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/mr-in.json @@ -1054,6 +1054,7 @@ "query-plural": "क्वेरी", "query-used-in": "क्वेरी वापरले", "queued": "Queued", + "raise-on-error": "त्रुटी आल्यास दर्शवा", "range": "श्रेणी", "range-condition": "श्रेणी अट", "re-assign": "पुन्हा नियुक्त करा", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json index 244a17bbb71..c094b988835 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/nl-nl.json @@ -1054,6 +1054,7 @@ "query-plural": "Query's", "query-used-in": "Query gebruikt in", "queued": "Queued", + "raise-on-error": "Fout bij uitvoeren weergeven", "range": "Bereik", "range-condition": "Bereikvoorwaarde", "re-assign": "Opnieuw toewijzen", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json index 9f5309a7c89..2411367d11d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pr-pr.json @@ -1054,6 +1054,7 @@ "query-plural": "پرس و جوها", "query-used-in": "پرس و جو استفاده شده در", "queued": "Queued", + "raise-on-error": "نمایش در صورت خطا", "range": "محدوده", "range-condition": "شرط محدوده", "re-assign": "دوباره تخصیص دهید", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json index d1109142f01..7b9d8d10904 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-br.json @@ -1054,6 +1054,7 @@ "query-plural": "Consultas", "query-used-in": "Consulta Usada em", "queued": "Queued", + "raise-on-error": "Mostrar erro ao executar", "range": "Faixa", "range-condition": "Condição de Intervalo", "re-assign": "Reassign", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json index 5d88aa1088a..65e670b6965 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/pt-pt.json @@ -1054,6 +1054,7 @@ "query-plural": "Consultas", "query-used-in": "Consulta Usada em", "queued": "Queued", + "raise-on-error": "Mostrar erro ao executar", "range": "Faixa", "range-condition": "Condição de Intervalo", "re-assign": "Reassign", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json index bb2a468c7a6..8ebd2b7243c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/ru-ru.json @@ -1054,6 +1054,7 @@ "query-plural": "Запросы", "query-used-in": "Запрос, используемый в", "queued": "Queued", + "raise-on-error": "Показывать ошибку при выполнении", "range": "Диапазон", "range-condition": "Условие Диапазона", "re-assign": "Reassign", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json index c795b56547c..68ab17cb57e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/th-th.json @@ -1054,6 +1054,7 @@ "query-plural": "การสอบถาม", "query-used-in": "การสอบถามที่ใช้ใน", "queued": "Queued", + "raise-on-error": "ยกเลิกการทำงาน", "range": "ช่วง", "range-condition": "เงื่อนไขช่วง", "re-assign": "มอบหมายใหม่", diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json index 4729ce8230b..ab59538a568 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/zh-cn.json @@ -1054,6 +1054,7 @@ "query-plural": "查询", "query-used-in": "查询语句被使用在", "queued": "排队中", + "raise-on-error": "出错时提示", "range": "范围", "range-condition": "范围条件", "re-assign": "重新分配", diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/SchedularUtils.tsx b/openmetadata-ui/src/main/resources/ui/src/utils/SchedularUtils.tsx index 563f47c3105..298b1c88932 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/SchedularUtils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/utils/SchedularUtils.tsx @@ -31,6 +31,7 @@ import { DEFAULT_SCHEDULE_CRON_WEEKLY, } from '../constants/Schedular.constants'; import { CronTypes } from '../enums/Schedular.enum'; +import { FieldTypes, FormItemLayout } from '../interface/FormUtils.interface'; export const getScheduleOptionsFromSchedules = ( scheduleOptions: string[] @@ -330,3 +331,22 @@ export const cronValidator = async (_: RuleObject, value: string) => { return Promise.resolve(); }; + +export const getRaiseOnErrorFormField = ( + onFocus?: (fieldName: string) => void +) => { + return { + name: 'raiseOnError', + label: t('label.raise-on-error'), + type: FieldTypes.SWITCH, + required: false, + formItemProps: { + valuePropName: 'checked', + }, + props: { + onFocus: () => onFocus?.('raiseOnError'), + }, + formItemLayout: FormItemLayout.HORIZONTAL, + id: 'root/raiseOnError', + }; +};