Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
faa2ae7
[Feature][Task] Add datavines task for data quality
zixi0825 Dec 1, 2024
8394ea5
[Fix][Task] Fix conflicts
zixi0825 Dec 1, 2024
501b9ff
[Fix][Task] Fix format issue
zixi0825 Dec 1, 2024
bce54a5
[Fix][Task] Fix img issue
zixi0825 Dec 1, 2024
6a12fe2
[Fix][Task] Add header
zixi0825 Dec 1, 2024
6976842
[Fix][Task] Fix docs issue
zixi0825 Dec 1, 2024
0db891c
[Fix][Task] Fix package issue
zixi0825 Dec 1, 2024
dac3c28
[Fix][Task] Fix format issue
zixi0825 Dec 1, 2024
0c1d483
[Fix][Task] Fix conflicts
zixi0825 Dec 1, 2024
28fdfd6
Merge branch 'dev' of https://github.com/apache/dolphinscheduler into…
zixi0825 Jan 27, 2025
8ad0a2a
[Fix][Task] Fix code style issue
zixi0825 Jan 28, 2025
27067af
[Fix][UI] Fix code style issue (1)
zixi0825 Jan 28, 2025
d496c2c
[Fix][Task] Fix build error
zixi0825 Jan 28, 2025
603b667
[Test][Task] Add datavines task tests
zixi0825 Jan 29, 2025
5d4691c
Merge branch 'dev' of https://github.com/apache/dolphinscheduler into…
zixi0825 Jan 29, 2025
e1f9084
[Fix][Task] Fix code style
zixi0825 Jan 29, 2025
0c7f248
[Fix][Task] Fix code style issue
zixi0825 Jan 29, 2025
8843539
[Test][Task] Add unit test
zixi0825 Jan 29, 2025
cd07963
[Fix][Task] Fix issues
zixi0825 Feb 9, 2025
3e60566
[Fix][Task] Fix issues
zixi0825 Feb 9, 2025
88a0a94
Merge branch 'dev' into dev-datavines
zixi0825 Feb 10, 2025
7267c70
Merge branch 'dev' into dev-datavines
zixi0825 Feb 12, 2025
73facf1
Merge branch 'dev' into dev-datavines
zixi0825 Feb 19, 2025
b4d2846
Merge branch 'dev' into dev-datavines
davidzollo Feb 26, 2025
7ba839c
Merge branch 'dev' into dev-datavines
zixi0825 Mar 20, 2025
45fee50
Merge branch 'dev' into dev-datavines
zixi0825 Mar 31, 2025
80363c0
Merge branch 'dev' into dev-datavines
zixi0825 Mar 31, 2025
a3d9828
Merge branch 'dev' into dev-datavines
zixi0825 Apr 2, 2025
0d69605
Merge branch 'dev' into dev-datavines
zixi0825 Apr 7, 2025
ba65bf6
Merge branch 'dev' into dev-datavines
zixi0825 Apr 8, 2025
315edd4
Merge branch 'dev' into dev-datavines
zixi0825 Apr 10, 2025
57a3efd
Merge branch 'dev' into dev-datavines
zixi0825 Apr 11, 2025
7925410
Merge branch 'dev' into dev-datavines
zixi0825 Apr 12, 2025
e038258
Merge branch 'dev' into dev-datavines
zixi0825 Apr 17, 2025
95550a3
Merge branch 'dev' into dev-datavines
zixi0825 Apr 18, 2025
4a179e9
Merge branch 'dev' into dev-datavines
zixi0825 Apr 20, 2025
386bba4
Merge branch 'dev' into dev-datavines
zixi0825 Apr 25, 2025
31a022c
Merge branch 'dev' into dev-datavines
zixi0825 May 29, 2025
03f2447
Merge branch 'dev' into dev-datavines
zixi0825 Jun 24, 2025
4c029a4
Merge branch 'dev' into dev-datavines
zixi0825 Jul 1, 2025
0e758a9
[Feature][Task] Add datavines task e2e
zixi0825 Apr 15, 2026
26a711e
[Feature][Task] Add datavines task e2e
zixi0825 Apr 15, 2026
b904cce
[Fix][Task] Fix format issue
zixi0825 Dec 1, 2024
255fbc3
[Fix][Task] Fix img issue
zixi0825 Dec 1, 2024
cd05769
[Fix][Task] Add header
zixi0825 Dec 1, 2024
c7cbf1f
[Fix][Task] Fix docs issue
zixi0825 Dec 1, 2024
9f10d3e
[Fix][Task] Fix conflict
zixi0825 Dec 1, 2024
58a032f
[Fix][Task] Fix format issue
zixi0825 Dec 1, 2024
efcb5b6
[Fix][Task] Fix conflicts
zixi0825 Dec 1, 2024
d5a8b38
[Fix][Task] Fix code style issue
zixi0825 Jan 28, 2025
376be7d
[Fix][UI] Fix code style issue (1)
zixi0825 Jan 28, 2025
a51e615
[Fix][Task] Fix build error
zixi0825 Jan 28, 2025
92037e4
[Test][Task] Add datavines task tests
zixi0825 Jan 29, 2025
2685a93
[Fix][Task] Fix code style
zixi0825 Jan 29, 2025
88b73fd
[Fix][Task] Fix code style issue
zixi0825 Jan 29, 2025
280f315
[Test][Task] Add unit test
zixi0825 Jan 29, 2025
de3a71f
[Fix][Task] Fix issues
zixi0825 Feb 9, 2025
dfe8eb0
[Fix][Task] Fix issues
zixi0825 Feb 9, 2025
3ec722e
[Feature][Task] Add datavines task e2e
zixi0825 Apr 15, 2026
7c67501
Merge remote-tracking branch 'origin/dev-datavines' into dev-datavines
zixi0825 Apr 15, 2026
3acaa23
[Feature][Task] Add datavines task test
zixi0825 Apr 15, 2026
42ad057
Merge branch 'dev' into dev-datavines
zixi0825 Apr 15, 2026
9b02337
[Fix][Task] Fix datavines task test
zixi0825 Apr 16, 2026
0304312
Merge remote-tracking branch 'origin/dev-datavines' into dev-datavines
zixi0825 Apr 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ jobs:
class: org.apache.dolphinscheduler.e2e.cases.HiveDataSourceE2ETest
- name: DolphinDBDataSourceE2ETest
class: org.apache.dolphinscheduler.e2e.cases.DolphinDBDataSourceE2ETest
- name: DatavinesTaskE2ETest
class: org.apache.dolphinscheduler.e2e.cases.tasks.DatavinesTaskE2ETest
env:
RECORDING_PATH: /tmp/recording-${{ matrix.case.name }}
steps:
Expand Down
30 changes: 30 additions & 0 deletions docs/docs/en/guide/task/datavines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Datavines

## Overview

Use `Datavines Task` to create a datavines-type task and support data quality job in Datavines. When the worker executes `Datavines Task`,
it will call `Datavines API` to trigger datavines job. Click [here](https://datavane.github.io/datavines-website/) for details about `Datavines`.

## Create Task

- Click Project Management-Project Name-Workflow Definition, and click the "Create Workflow" button to enter the DAG editing page.
- Drag <img src="../../../../img/tasks/icons/datavines.png" width="15"/> from the toolbar to the canvas.

## Task Parameter

- Please refer to [DolphinScheduler Task Parameters Appendix](appendix.md) `Default Task Parameters` section for default parameters.

| **Parameter** | **Description** |
|-------------------|-------------------------------------------------------------------------------------------------------|
| Datavines Address | The URL for the Datavines service, e.g., http://localhost:5600. |
| Datavines Job ID | The unique job id for a datavines job. |
| Datavines token | The Datavines service access token can be obtained through token management on the Datavines service. |
| Block on Failure | When turned on, if the data quality check result is failed, the task result will be set as failed. |

## Task Example

This example illustrates how to create a datavines task node.

![demo-datavines](../../../../img/tasks/demo/datavines_task.png)

![demo-get-datavines-job-id](../../../../img/tasks/demo/datavines_job_id.png)
31 changes: 31 additions & 0 deletions docs/docs/zh/guide/task/datavines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Datavines

## 综述

`Datavines`任务类型,用于创建并执行 `Datavines` 类型任务来执行 Datavines 中的数据质量检查作业。Worker 执行该任务的时候,会通过 `Datavines API` 触发 `Datavines 的作业`。
点击 [这里](https://datavane.github.io/datavines-website/) 获取更多关于 `Datavines` 的信息。

## 创建任务

- 点击项目管理-项目名称-工作流定义,点击"创建工作流"按钮,进入DAG编辑页面。
- 工具栏中拖动 <img src="../../../../img/tasks/icons/datavines.png" width="15"/> 到画板中,即可完成创建。

## 任务参数

- 默认参数说明请参考[DolphinScheduler任务参数附录](appendix.md)`默认任务参数`一栏。

| **任务参数** | **描述** |
|-----------------|------------------------------------------------------|
| Datavines 地址 | Datavines 服务的 url,例如:`http://localhost:5600`。 |
| Datavines 作业 ID | Datavines 作业对应的唯一ID。 |
| Datavines token | Datavines 服务访问 token, 可在 Datavines 服务上的 token 管理中取得。 |
| 检查失败时阻塞 | 开启时,数据质量检查结果为失败时会将任务结果置为失败。 |

## 例子

这个示例展示了如何创建 Datavines 任务节点:

![demo-datavines](../../../../img/tasks/demo/datavines_task.png)

![demo-get-datavines-job-id](../../../../img/tasks/demo/datavines_job_id.png)

Binary file added docs/img/tasks/demo/datavines_job_id.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/tasks/demo/datavines_task.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/tasks/icons/datavines.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ task:
- 'SEATUNNEL'
- 'DATAX'
- 'SQOOP'
dataQuality:
- 'DATAVINES'
machineLearning:
- 'JUPYTER'
- 'MLFLOW'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.dolphinscheduler.e2e.cases.tasks;

import static org.assertj.core.api.Assertions.assertThat;

import org.apache.dolphinscheduler.e2e.cases.workflow.BaseWorkflowE2ETest;
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler;
import org.apache.dolphinscheduler.e2e.core.WebDriverHolder;
import org.apache.dolphinscheduler.e2e.pages.LoginPage;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.TaskInstanceTab;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.DatavinesTaskForm;
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage;
import org.apache.dolphinscheduler.e2e.pages.security.TenantPage;
import org.apache.dolphinscheduler.e2e.pages.security.UserPage;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junitpioneer.jupiter.DisableIfTestFails;

@TestMethodOrder(MethodOrderer.MethodName.class)
@DolphinScheduler(composeFiles = "docker/datavines-task/docker-compose.yaml")
@DisableIfTestFails
public class DatavinesTaskE2ETest extends BaseWorkflowE2ETest {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add this to

- name: DolphinDBDataSourceE2ETest
class: org.apache.dolphinscheduler.e2e.cases.DolphinDBDataSourceE2ETest


private static final String mockServerAddress = "http://mockServer:1080";

private static final String jobId = "1";

private static final String token = "test-token";

@BeforeAll
public static void setup() {
browser = WebDriverHolder.getWebDriver();

TenantPage tenantPage = new LoginPage(browser)
.login(adminUser)
.goToNav(SecurityPage.class)
.goToTab(TenantPage.class);

if (tenantPage.tenants().stream().noneMatch(tenant -> tenant.tenantCode().equals(adminUser.getTenant()))) {
tenantPage
.create(adminUser.getTenant())
.goToNav(SecurityPage.class)
.goToTab(UserPage.class)
.update(adminUser);
}

tenantPage
.goToNav(ProjectPage.class)
.createProjectUntilSuccess(projectName);
}

@Test
@Order(10)
void testRunDatavinesTasks_SuccessCase() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to add a failed test case.

WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser)
.goToNav(ProjectPage.class)
.goTo(projectName)
.goToTab(WorkflowDefinitionTab.class);

String workflowName = "DatavinesSuccessCase";
String taskName = "DatavinesSuccessTask";
workflowDefinitionPage
.createWorkflow()
.<DatavinesTaskForm>addTask(WorkflowForm.TaskType.DATAVINES)
.address(mockServerAddress)
.jobId(jobId)
.token(token)
.name(taskName)
.submit()

.submit()
.name(workflowName)
.submit();

untilWorkflowDefinitionExist(workflowName);

workflowDefinitionPage.publish(workflowName);

runWorkflow(workflowName);
untilWorkflowInstanceExist(workflowName);
WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName);
assertThat(workflowInstance.executionTime()).isEqualTo(1);

TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName);
assertThat(taskInstance.retryTimes()).isEqualTo(0);
}

@Test
@Order(20)
void testRunDatavinesTasks_FailureBlockDisabledCase() {
WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser)
.goToNav(ProjectPage.class)
.goTo(projectName)
.goToTab(WorkflowDefinitionTab.class);

String workflowName = "DatavinesFailureBlockDisabledCase";
String taskName = "DatavinesFailureBlockDisabledTask";
workflowDefinitionPage
.createWorkflow()
.<DatavinesTaskForm>addTask(WorkflowForm.TaskType.DATAVINES)
.address(mockServerAddress)
.jobId(jobId)
.token(token)
.name(taskName)
.submit()

.submit()
.name(workflowName)
.submit();

untilWorkflowDefinitionExist(workflowName);

workflowDefinitionPage.publish(workflowName);

runWorkflow(workflowName);
untilWorkflowInstanceExist(workflowName);
WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceSuccess(workflowName);
assertThat(workflowInstance.executionTime()).isEqualTo(1);

TaskInstanceTab.Row taskInstance = untilTaskInstanceSuccess(workflowName, taskName);
assertThat(taskInstance.retryTimes()).isEqualTo(0);
}

@Test
@Order(30)
void testRunDatavinesTasks_FailureCase() {
WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser)
.goToNav(ProjectPage.class)
.goTo(projectName)
.goToTab(WorkflowDefinitionTab.class);

String workflowName = "DatavinesFailureCase";
String taskName = "DatavinesFailureTask";
// Job ID "2" is configured in MockServer to return execution status FAILURE
workflowDefinitionPage
.createWorkflow()
.<DatavinesTaskForm>addTask(WorkflowForm.TaskType.DATAVINES)
.address(mockServerAddress)
.jobId("2")
.token(token)
.name(taskName)
.submit()

.submit()
.name(workflowName)
.submit();

untilWorkflowDefinitionExist(workflowName);

workflowDefinitionPage.publish(workflowName);

runWorkflow(workflowName);
untilWorkflowInstanceExist(workflowName);
WorkflowInstanceTab.Row workflowInstance = untilWorkflowInstanceFailed(workflowName);
assertThat(workflowInstance.executionTime()).isEqualTo(1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.apache.dolphinscheduler.e2e.pages.project.workflow;

import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.DatavinesTaskForm;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.HttpTaskForm;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.JavaTaskForm;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.PythonTaskForm;
Expand Down Expand Up @@ -90,6 +91,8 @@ public <T> T addTask(TaskType type) {
return (T) new JavaTaskForm(this);
case PYTHON:
return (T) new PythonTaskForm(this);
case DATAVINES:
return (T) new DatavinesTaskForm(this);
}
throw new UnsupportedOperationException("Unknown task type");
}
Expand Down Expand Up @@ -129,6 +132,7 @@ public enum TaskType {
SWITCH,
HTTP,
JAVA,
PYTHON
PYTHON,
DATAVINES
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.dolphinscheduler.e2e.pages.project.workflow.task;

import org.apache.dolphinscheduler.e2e.core.WebDriverWaitFactory;
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;

public final class DatavinesTaskForm extends TaskNodeForm {

private final WebDriver driver;

@FindBys({
@FindBy(className = "input-datavines-address"),
@FindBy(tagName = "input")
})
private WebElement addressInput;

@FindBys({
@FindBy(className = "input-datavines-job-id"),
@FindBy(tagName = "input")
})
private WebElement jobIdInput;

@FindBys({
@FindBy(className = "input-datavines-token"),
@FindBy(tagName = "input")
})
private WebElement tokenInput;

public DatavinesTaskForm(WorkflowForm parent) {
super(parent);
this.driver = parent.driver();
PageFactory.initElements(driver, this);
}

public DatavinesTaskForm address(String address) {
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(addressInput));
addressInput.sendKeys(address);
return this;
}

public DatavinesTaskForm jobId(String jobId) {
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(jobIdInput));
jobIdInput.sendKeys(jobId);
return this;
}

public DatavinesTaskForm token(String token) {
WebDriverWaitFactory.createWebDriverWait(driver)
.until(ExpectedConditions.elementToBeClickable(tokenInput));
tokenInput.sendKeys(token);
return this;
}
}
Loading
Loading