localParams = Collections.emptyList();
25 |
26 | @Override
27 | public String getTaskType() {
28 | return "PROCEDURE";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/task/TaskResource.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.task;
2 |
3 | import com.github.weaksloth.dolphins.remote.RequestHttpEntity;
4 | import com.github.weaksloth.dolphins.util.JacksonUtils;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | /**
10 | * used by shell,python,spark,flink.... task
11 | *
12 | * used when define task
13 | */
14 | @Data
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | public class TaskResource {
18 |
19 | private Long id;
20 |
21 | /**
22 | * must rewrite,then {@link RequestHttpEntity#bodyToMap()} can transfer object to json string
23 | *
24 | * @return object json string
25 | */
26 | @Override
27 | public String toString() {
28 | return JacksonUtils.toJSONString(this);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/taskinstance/TaskInstanceTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.taskinstance;
2 |
3 | import com.github.weaksloth.dolphins.BaseTest;
4 | import java.util.List;
5 | import org.junit.Test;
6 |
7 | public class TaskInstanceTest extends BaseTest {
8 |
9 | @Test
10 | public void testPage() {
11 | Long processInstanceId = 1L;
12 | List taskInstanceQueryResps =
13 | getClient().opsForTaskInstance().page(projectCode, null, null, processInstanceId);
14 |
15 | taskInstanceQueryResps.forEach(System.out::println);
16 | }
17 |
18 | @Test
19 | public void testQueryLog() {
20 | Long taskInstanceId = 1L;
21 | String log = getClient().opsForTaskInstance().queryLog(projectCode, null, null, taskInstanceId);
22 |
23 | System.out.println(log);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/ReleaseState.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | /** process define release state */
4 | public enum ReleaseState {
5 |
6 | /** 0 offline 1 online */
7 | OFFLINE(0, "offline"),
8 | ONLINE(1, "online");
9 |
10 | ReleaseState(int code, String descp) {
11 | this.code = code;
12 | this.descp = descp;
13 | }
14 |
15 | private final int code;
16 | private final String descp;
17 |
18 | public static ReleaseState getEnum(int value) {
19 | for (ReleaseState e : ReleaseState.values()) {
20 | if (e.ordinal() == value) {
21 | return e;
22 | }
23 | }
24 | // For values out of enum scope
25 | return null;
26 | }
27 |
28 | public int getCode() {
29 | return code;
30 | }
31 |
32 | public String getDescp() {
33 | return descp;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/process/TaskLocation.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.process;
2 |
3 | import com.github.weaksloth.dolphins.remote.RequestHttpEntity;
4 | import com.github.weaksloth.dolphins.util.JacksonUtils;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import lombok.experimental.Accessors;
9 |
10 | @Data
11 | @AllArgsConstructor
12 | @NoArgsConstructor
13 | @Accessors(chain = true)
14 | public class TaskLocation {
15 |
16 | private Long taskCode;
17 |
18 | private int x;
19 |
20 | private int y;
21 |
22 | /**
23 | * must rewrite,then {@link RequestHttpEntity#bodyToMap()} can transfer object to json string
24 | *
25 | * @return object json string
26 | */
27 | @Override
28 | public String toString() {
29 | return JacksonUtils.toJSONString(this);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/task/PythonTask.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.task;
2 |
3 | import com.github.weaksloth.dolphins.process.Parameter;
4 | import java.util.Collections;
5 | import java.util.List;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | /** reference: org.apache.dolphinscheduler.plugin.task.python.PythonParameters */
11 | @EqualsAndHashCode(callSuper = true)
12 | @Data
13 | @Accessors(chain = true)
14 | public class PythonTask extends AbstractTask {
15 |
16 | /** resource list */
17 | private List resourceList = Collections.emptyList();
18 |
19 | private List localParams = Collections.emptyList();
20 |
21 | /** python script */
22 | private String rawScript;
23 |
24 | @Override
25 | public String getTaskType() {
26 | return "PYTHON";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/datasource/DataSourceCreateParam.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.datasource;
2 |
3 | import java.util.Map;
4 | import lombok.Data;
5 | import lombok.experimental.Accessors;
6 |
7 | /** create datasource param */
8 | @Data
9 | @Accessors(chain = true)
10 | public class DataSourceCreateParam {
11 |
12 | private String database;
13 |
14 | private String host;
15 |
16 | private String name;
17 |
18 | private String userName;
19 |
20 | private String password;
21 |
22 | private String type;
23 |
24 | private String port;
25 |
26 | private String note;
27 |
28 | /**
29 | * this param is useful when creating oracle datasource
30 | *
31 | * example value: ORACLE_SERVICE_NAME
32 | */
33 | private String connectType;
34 |
35 | /** jdbc connect params, json example: {"useServerPrepStmts":"true","useSSL":"false"} */
36 | private Map other;
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/process/TaskRelation.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.process;
2 |
3 | import com.github.weaksloth.dolphins.remote.RequestHttpEntity;
4 | import com.github.weaksloth.dolphins.util.JacksonUtils;
5 | import lombok.Data;
6 | import lombok.experimental.Accessors;
7 |
8 | @Data
9 | @Accessors(chain = true)
10 | public class TaskRelation {
11 |
12 | private String name = "";
13 |
14 | private Long preTaskCode = 0L;
15 |
16 | private Integer preTaskVersion = 0;
17 |
18 | private Long postTaskCode;
19 |
20 | private Integer postTaskVersion = 0;
21 |
22 | private Integer conditionType = 0;
23 |
24 | private Integer conditionParams;
25 |
26 | /**
27 | * must rewrite,then {@link RequestHttpEntity#bodyToMap()} can transfer object to json string
28 | *
29 | * @return object json string
30 | */
31 | @Override
32 | public String toString() {
33 | return JacksonUtils.toJSONString(this);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/core/AbstractOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.core;
2 |
3 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
4 | import com.github.weaksloth.dolphins.remote.Header;
5 |
6 | public abstract class AbstractOperator {
7 |
8 | protected final String dolphinAddress;
9 |
10 | private final String token;
11 |
12 | protected final DolphinsRestTemplate dolphinsRestTemplate;
13 |
14 | public AbstractOperator(
15 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
16 | this.dolphinAddress = dolphinAddress;
17 | this.token = token;
18 | this.dolphinsRestTemplate = dolphinsRestTemplate;
19 | }
20 |
21 | /**
22 | * get header for dolphin scheduler
23 | *
24 | * @return
25 | */
26 | protected Header getHeader() {
27 | Header header = Header.newInstance();
28 | header.addParam("token", this.token);
29 | return header;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/tenant/TenantInfoResp.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.tenant;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import java.util.Date;
5 | import lombok.Data;
6 |
7 | /** tenant info resp, copied from org.apache.dolphinscheduler.dao.entity.Tenant */
8 | @Data
9 | public class TenantInfoResp {
10 |
11 | /** id */
12 | private Integer id;
13 |
14 | /** tenant code */
15 | private String tenantCode;
16 |
17 | /** description */
18 | private String description;
19 |
20 | /** queue id */
21 | private int queueId;
22 |
23 | /** queue name */
24 | private String queueName;
25 |
26 | /** queue */
27 | private String queue;
28 |
29 | /** create time */
30 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
31 | private Date createTime;
32 |
33 | /** update time */
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date updateTime;
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/datasource/DataSourceQueryResp.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.datasource;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import java.util.Date;
5 | import lombok.Data;
6 |
7 | /** query datasource info response,copied from org.apache.dolphinscheduler.dao.entity.DataSource */
8 | @Data
9 | public class DataSourceQueryResp {
10 |
11 | private Long id;
12 |
13 | /** user id */
14 | private int userId;
15 |
16 | /** user name */
17 | private String userName;
18 |
19 | /** data source name */
20 | private String name;
21 |
22 | /** note */
23 | private String note;
24 |
25 | /** data source type */
26 | private String type;
27 |
28 | /** connection parameters */
29 | private String connectionParams;
30 |
31 | /** create time */
32 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
33 | private Date createTime;
34 |
35 | /** update time */
36 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
37 | private Date updateTime;
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/schedule/ScheduleDefineParam.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.schedule;
2 |
3 | import com.github.weaksloth.dolphins.util.JacksonUtils;
4 | import lombok.Data;
5 | import lombok.experimental.Accessors;
6 |
7 | @Data
8 | @Accessors(chain = true)
9 | public class ScheduleDefineParam {
10 |
11 | private Schedule schedule;
12 |
13 | private String failureStrategy = "END";
14 |
15 | private String warningType = "NONE";
16 |
17 | private String processInstancePriority = "MEDIUM";
18 |
19 | private String warningGroupId = "0";
20 |
21 | private String workerGroup = "default";
22 |
23 | private String environmentCode = "";
24 |
25 | private Long processDefinitionCode;
26 |
27 | @Data
28 | @Accessors(chain = true)
29 | public static class Schedule {
30 | private String startTime;
31 | private String endTime;
32 | private String crontab;
33 | private String timezoneId = "Asia/Shanghai"; // default time zone
34 |
35 | @Override
36 | public String toString() {
37 | return JacksonUtils.toJSONString(this);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/instance/ProcessInstanceCreateParam.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.instance;
2 |
3 | import lombok.Data;
4 | import lombok.experimental.Accessors;
5 |
6 | /** process instance create param */
7 | @Data
8 | @Accessors(chain = true)
9 | public class ProcessInstanceCreateParam {
10 |
11 | /** continue or and */
12 | private String failureStrategy;
13 |
14 | private Long processDefinitionCode;
15 |
16 | private String processInstancePriority;
17 |
18 | private String scheduleTime;
19 |
20 | private Long warningGroupId;
21 |
22 | private String warningType;
23 |
24 | /** o or 1 */
25 | private Integer dryRun;
26 |
27 | /** env code */
28 | private String environmentCode;
29 |
30 | private String execType;
31 |
32 | private String expectedParallelismNumber;
33 |
34 | /** run mode,value:RUN_MODE_SERIAL,RUN_MODE_PARALLEL */
35 | private String runMode;
36 |
37 | private String startNodeList;
38 |
39 | private String startParams;
40 |
41 | private String taskDependType;
42 |
43 | /** worker group */
44 | private String workerGroup;
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/ConditionType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /** condition type */
7 | public enum ConditionType {
8 |
9 | /** 0 none 1 judge 2 delay */
10 | NONE(0, "none"),
11 | JUDGE(1, "judge"),
12 | DELAY(2, "delay");
13 |
14 | ConditionType(int code, String desc) {
15 | this.code = code;
16 | this.desc = desc;
17 | }
18 |
19 | private final int code;
20 | private final String desc;
21 |
22 | public int getCode() {
23 | return code;
24 | }
25 |
26 | public String getDesc() {
27 | return desc;
28 | }
29 |
30 | private static final Map CONDITION_TYPE_MAP = new HashMap<>();
31 |
32 | static {
33 | for (ConditionType conditionType : ConditionType.values()) {
34 | CONDITION_TYPE_MAP.put(conditionType.desc, conditionType);
35 | }
36 | }
37 |
38 | public static ConditionType of(String desc) {
39 | if (CONDITION_TYPE_MAP.containsKey(desc)) {
40 | return CONDITION_TYPE_MAP.get(desc);
41 | }
42 | throw new IllegalArgumentException("invalid type : " + desc);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/process/ProcessReleaseParam.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.process;
2 |
3 | import lombok.Data;
4 | import lombok.experimental.Accessors;
5 |
6 | @Data
7 | @Accessors(chain = true)
8 | public class ProcessReleaseParam {
9 |
10 | public static final String ONLINE_STATE = "ONLINE";
11 | public static final String OFFLINE_STATE = "OFFLINE";
12 |
13 | /** workflow name, this field is not necessary, the dolphin scheduler rest api is shit!!! */
14 | private String name;
15 |
16 | /** workflow state: ONLINE or OFFLINE */
17 | private String releaseState;
18 |
19 | /**
20 | * create instance with online state
21 | *
22 | * @return {@link ProcessReleaseParam} with online state
23 | */
24 | public static ProcessReleaseParam newOnlineInstance() {
25 | return new ProcessReleaseParam().setReleaseState(ONLINE_STATE);
26 | }
27 |
28 | /**
29 | * create instance with offline state
30 | *
31 | * @return {@link ProcessReleaseParam} with offline state
32 | */
33 | public static ProcessReleaseParam newOfflineInstance() {
34 | return new ProcessReleaseParam().setReleaseState(OFFLINE_STATE);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/project/ProjectInfoResp.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.project;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import java.util.Date;
5 | import lombok.Data;
6 |
7 | /** create project response,copied from org.apache.dolphinscheduler.dao.entity.Project */
8 | @Data
9 | public class ProjectInfoResp {
10 |
11 | /** id */
12 | private int id;
13 |
14 | /** user id */
15 | private int userId;
16 |
17 | /** user name */
18 | private String userName;
19 |
20 | /** project code */
21 | private long code;
22 |
23 | /** project name */
24 | private String name;
25 |
26 | /** project description */
27 | private String description;
28 |
29 | /** create time */
30 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
31 | private Date createTime;
32 |
33 | /** update time */
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date updateTime;
36 |
37 | /** permission */
38 | private int perm;
39 |
40 | /** process define count */
41 | private int defCount;
42 |
43 | /** process instance running count */
44 | private int instRunningCount;
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/TaskGroupQueueStatus.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 |
5 | /** running status for task group queue */
6 | public enum TaskGroupQueueStatus {
7 | WAIT_QUEUE(-1, "wait queue"),
8 | ACQUIRE_SUCCESS(1, "acquire success"),
9 | RELEASE(2, "release");
10 |
11 | private final int code;
12 | private final String descp;
13 | private static HashMap STATUS_MAP = new HashMap<>();
14 |
15 | static {
16 | for (TaskGroupQueueStatus taskGroupQueueStatus : TaskGroupQueueStatus.values()) {
17 | STATUS_MAP.put(taskGroupQueueStatus.code, taskGroupQueueStatus);
18 | }
19 | }
20 |
21 | TaskGroupQueueStatus(int code, String descp) {
22 | this.code = code;
23 | this.descp = descp;
24 | }
25 |
26 | public static TaskGroupQueueStatus of(int status) {
27 | if (STATUS_MAP.containsKey(status)) {
28 | return STATUS_MAP.get(status);
29 | }
30 | throw new IllegalArgumentException("invalid status : " + status);
31 | }
32 |
33 | public int getCode() {
34 | return code;
35 | }
36 |
37 | public String getDescp() {
38 | return descp;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/AuditOperationType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 |
5 | /** Audit Operation type */
6 | public enum AuditOperationType {
7 | CREATE(0, "CREATE"),
8 | READ(1, "READ"),
9 | UPDATE(2, "UPDATE"),
10 | DELETE(3, "DELETE");
11 |
12 | private final int code;
13 | private final String enMsg;
14 |
15 | private static HashMap AUDIT_OPERATION_MAP = new HashMap<>();
16 |
17 | static {
18 | for (AuditOperationType operationType : AuditOperationType.values()) {
19 | AUDIT_OPERATION_MAP.put(operationType.code, operationType);
20 | }
21 | }
22 |
23 | AuditOperationType(int code, String enMsg) {
24 | this.code = code;
25 | this.enMsg = enMsg;
26 | }
27 |
28 | public static AuditOperationType of(int status) {
29 | if (AUDIT_OPERATION_MAP.containsKey(status)) {
30 | return AUDIT_OPERATION_MAP.get(status);
31 | }
32 | throw new IllegalArgumentException("invalid audit operation type code " + status);
33 | }
34 |
35 | public int getCode() {
36 | return code;
37 | }
38 |
39 | public String getMsg() {
40 | return enMsg;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/AuditResourceType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 |
5 | /** Audit Module type */
6 | public enum AuditResourceType {
7 |
8 | // TODO: add other audit resource enums
9 | USER_MODULE(0, "USER"),
10 | PROJECT_MODULE(1, "PROJECT");
11 |
12 | private final int code;
13 | private final String enMsg;
14 |
15 | private static HashMap AUDIT_RESOURCE_MAP = new HashMap<>();
16 |
17 | static {
18 | for (AuditResourceType auditResourceType : AuditResourceType.values()) {
19 | AUDIT_RESOURCE_MAP.put(auditResourceType.code, auditResourceType);
20 | }
21 | }
22 |
23 | AuditResourceType(int code, String enMsg) {
24 | this.code = code;
25 | this.enMsg = enMsg;
26 | }
27 |
28 | public int getCode() {
29 | return this.code;
30 | }
31 |
32 | public String getMsg() {
33 | return this.enMsg;
34 | }
35 |
36 | public static AuditResourceType of(int status) {
37 | if (AUDIT_RESOURCE_MAP.containsKey(status)) {
38 | return AUDIT_RESOURCE_MAP.get(status);
39 | }
40 | throw new IllegalArgumentException("invalid audit resource type code " + status);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/PluginType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 |
5 | /** PluginType */
6 | public enum PluginType {
7 | ALERT(1, "alert", true),
8 | REGISTER(2, "register", false),
9 | TASK(3, "task", true);
10 |
11 | PluginType(int code, String desc, boolean hasUi) {
12 | this.code = code;
13 | this.desc = desc;
14 | this.hasUi = hasUi;
15 | }
16 |
17 | private final int code;
18 | private final String desc;
19 | private final boolean hasUi;
20 |
21 | public int getCode() {
22 | return code;
23 | }
24 |
25 | public String getDesc() {
26 | return desc;
27 | }
28 |
29 | public boolean getHasUi() {
30 | return hasUi;
31 | }
32 |
33 | private static HashMap PLUGIN_TYPE_MAP = new HashMap<>();
34 |
35 | static {
36 | for (PluginType pluginType : PluginType.values()) {
37 | PLUGIN_TYPE_MAP.put(pluginType.getCode(), pluginType);
38 | }
39 | }
40 |
41 | public static PluginType of(int type) {
42 | if (PLUGIN_TYPE_MAP.containsKey(type)) {
43 | return PLUGIN_TYPE_MAP.get(type);
44 | }
45 | throw new IllegalArgumentException("invalid type : " + type);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/AlertType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | /** describe the reason why alert generates */
4 | public enum AlertType {
5 |
6 | /**
7 | * 0 process instance failure, 1 process instance success, 2 process instance blocked, 3 process
8 | * instance timeout, 4 fault tolerance warning, 5 task failure, 6 task success, 7 task timeout, 8
9 | * close alert
10 | */
11 | PROCESS_INSTANCE_FAILURE(0, "process instance failure"),
12 | PROCESS_INSTANCE_SUCCESS(1, "process instance success"),
13 | PROCESS_INSTANCE_BLOCKED(2, "process instance blocked"),
14 | PROCESS_INSTANCE_TIMEOUT(3, "process instance timeout"),
15 | FAULT_TOLERANCE_WARNING(4, "fault tolerance warning"),
16 | TASK_FAILURE(5, "task failure"),
17 | TASK_SUCCESS(6, "task success"),
18 | TASK_TIMEOUT(7, "task timeout"),
19 |
20 | CLOSE_ALERT(8, "the process instance success, can close the before alert");
21 |
22 | AlertType(int code, String descp) {
23 | this.code = code;
24 | this.descp = descp;
25 | }
26 |
27 | private final int code;
28 | private final String descp;
29 |
30 | public int getCode() {
31 | return code;
32 | }
33 |
34 | public String getDescp() {
35 | return descp;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/BaseTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins;
2 |
3 | import com.github.weaksloth.dolphins.core.DolphinClient;
4 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
5 | import com.github.weaksloth.dolphins.remote.request.DefaultHttpClientRequest;
6 | import org.apache.http.client.config.RequestConfig;
7 | import org.apache.http.impl.client.HttpClients;
8 | import org.apache.http.protocol.RequestContent;
9 |
10 | public class BaseTest {
11 |
12 | protected final String dolphinAddress = "http://localhost:12345/dolphinscheduler";
13 | protected final Long projectCode = 8920447405632L;
14 | private final String token = "e8438bb6324f2832cc6bd416566e8c64";
15 | protected final String tenantCode = "chen";
16 |
17 | protected DolphinsRestTemplate restTemplate =
18 | new DolphinsRestTemplate(
19 | new DefaultHttpClientRequest(
20 | HttpClients.custom()
21 | .addInterceptorLast(new RequestContent(true))
22 | .setDefaultRequestConfig(RequestConfig.custom().build())
23 | .build(),
24 | RequestConfig.custom().build()));
25 |
26 | protected DolphinClient getClient() {
27 | return new DolphinClient(token, dolphinAddress, restTemplate);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/DbTypeEnum.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import static java.util.stream.Collectors.toMap;
4 |
5 | import com.google.common.base.Functions;
6 | import java.util.Arrays;
7 | import java.util.Map;
8 |
9 | /** copied from org.apache.dolphinscheduler.spi.enums.DbType */
10 | public enum DbTypeEnum {
11 | MYSQL(0, "mysql"),
12 | POSTGRESQL(1, "postgresql"),
13 | HIVE(2, "hive"),
14 | SPARK(3, "spark"),
15 | CLICKHOUSE(4, "clickhouse"),
16 | ORACLE(5, "oracle"),
17 | SQLSERVER(6, "sqlserver"),
18 | DB2(7, "db2"),
19 | PRESTO(8, "presto"),
20 | H2(9, "h2");
21 |
22 | private final int code;
23 | private final String descp;
24 |
25 | DbTypeEnum(int code, String descp) {
26 | this.code = code;
27 | this.descp = descp;
28 | }
29 |
30 | public int getCode() {
31 | return code;
32 | }
33 |
34 | public String getDescp() {
35 | return descp;
36 | }
37 |
38 | private static final Map DB_TYPE_MAP =
39 | Arrays.stream(DbTypeEnum.values()).collect(toMap(DbTypeEnum::getCode, Functions.identity()));
40 |
41 | public static DbTypeEnum of(int type) {
42 | if (DB_TYPE_MAP.containsKey(type)) {
43 | return DB_TYPE_MAP.get(type);
44 | }
45 | return null;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/task/SqlTask.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.task;
2 |
3 | import java.util.List;
4 | import lombok.Data;
5 | import lombok.experimental.Accessors;
6 |
7 | /** copied from org.apache.dolphinscheduler.plugin.task.api.parameters.SqlParameters */
8 | @Data
9 | @Accessors(chain = true)
10 | public class SqlTask extends AbstractTask {
11 |
12 | /** data source type,eg MYSQL, POSTGRES, HIVE ... */
13 | private String type;
14 |
15 | /** datasource id */
16 | private Integer datasource;
17 |
18 | /** sql */
19 | private String sql;
20 |
21 | /** sql type 0 query 1 NON_QUERY */
22 | private String sqlType;
23 |
24 | /** send email */
25 | private Boolean sendEmail;
26 |
27 | /** display rows */
28 | private Integer displayRows;
29 |
30 | /** udf list */
31 | private String udfs;
32 |
33 | /** SQL connection parameters */
34 | private String connParams;
35 |
36 | /** Pre Statements */
37 | private List preStatements;
38 |
39 | /** Post Statements */
40 | private List postStatements;
41 |
42 | /** groupId */
43 | private Integer groupId;
44 |
45 | /** title */
46 | private String title;
47 |
48 | private Integer limit;
49 |
50 | @Override
51 | public String getTaskType() {
52 | return "SQL";
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/resource/ResourceQueryRes.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.resource;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import java.util.Date;
6 | import lombok.Data;
7 |
8 | /** copied from org.apache.dolphinscheduler.dao.entity.Resource */
9 | @Data
10 | @JsonIgnoreProperties(ignoreUnknown = true)
11 | public class ResourceQueryRes {
12 |
13 | /** id */
14 | private int id;
15 |
16 | /** parent id */
17 | private int pid;
18 |
19 | /** resource alias */
20 | private String alias;
21 |
22 | /** full name */
23 | private String fullName;
24 |
25 | /** is directory */
26 | private boolean isDirectory = false;
27 |
28 | /** description */
29 | private String description;
30 |
31 | /** file alias */
32 | private String fileName;
33 |
34 | private String userName;
35 |
36 | /** user id */
37 | private int userId;
38 |
39 | /** resource type */
40 | private String type;
41 |
42 | /** resource size */
43 | private long size;
44 |
45 | /** create time */
46 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
47 | private Date createTime;
48 |
49 | /** update time */
50 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
51 | private Date updateTime;
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/WarningType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import static java.util.stream.Collectors.toMap;
4 |
5 | import com.google.common.base.Functions;
6 | import java.util.Arrays;
7 | import java.util.Map;
8 |
9 | /** types for whether to send warning when process ends; */
10 | public enum WarningType {
11 |
12 | /**
13 | * 0 do not send warning; 1 send if process success; 2 send if process failed; 3 send if process
14 | * ends, whatever the result; 4 send global events;
15 | */
16 | NONE(0, "none"),
17 | SUCCESS(1, "success"),
18 | FAILURE(2, "failure"),
19 | ALL(3, "all"),
20 | GLOBAL(4, "global");
21 |
22 | WarningType(int code, String descp) {
23 | this.code = code;
24 | this.descp = descp;
25 | }
26 |
27 | private final int code;
28 | private final String descp;
29 |
30 | public int getCode() {
31 | return code;
32 | }
33 |
34 | public String getDescp() {
35 | return descp;
36 | }
37 |
38 | private static final Map WARNING_TYPE_MAP =
39 | Arrays.stream(WarningType.values())
40 | .collect(toMap(WarningType::getDescp, Functions.identity()));
41 |
42 | public static WarningType of(String descp) {
43 | if (WARNING_TYPE_MAP.containsKey(descp)) {
44 | return WARNING_TYPE_MAP.get(descp);
45 | }
46 | return null;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/util/TaskRelationUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.util;
2 |
3 | import com.github.weaksloth.dolphins.process.TaskRelation;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | /** utils for build task relation */
8 | public class TaskRelationUtils {
9 |
10 | /**
11 | * this method is used for graph edge set task one by one relation,such as t1->t2->t3->t4.....
12 | *
13 | * @param taskCodes task codes
14 | * @return {@link List}
15 | */
16 | public static List oneLineRelation(Long... taskCodes) {
17 | List list = new ArrayList<>();
18 | for (int i = 0; i < taskCodes.length; i++) {
19 | if (i == 0) {
20 | list.add(new TaskRelation().setPostTaskCode(taskCodes[i]));
21 | } else {
22 | list.add(new TaskRelation().setPreTaskCode(taskCodes[i - 1]).setPostTaskCode(taskCodes[i]));
23 | }
24 | }
25 | return list;
26 | }
27 |
28 | /**
29 | * this method is used for graph edge all task is alone,no relation,such as t1 t2 t3
30 | *
31 | * @param taskCodes task codes
32 | * @return {@link List}
33 | */
34 | public static List noRelation(Long... taskCodes) {
35 | List list = new ArrayList<>();
36 | for (Long taskCode : taskCodes) {
37 | list.add(new TaskRelation().setPostTaskCode(taskCode));
38 | }
39 | return list;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/response/DefaultHttpClientResponse.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote.response;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.LinkedHashMap;
6 | import java.util.Map;
7 | import org.apache.http.Header;
8 | import org.apache.http.HttpResponse;
9 | import org.apache.http.client.utils.HttpClientUtils;
10 |
11 | public class DefaultHttpClientResponse implements HttpClientResponse {
12 |
13 | private HttpResponse response;
14 |
15 | private Map responseHeaders;
16 |
17 | public DefaultHttpClientResponse(HttpResponse response) {
18 | this.response = response;
19 | }
20 |
21 | @Override
22 | public Map getHeaders() {
23 | if (this.responseHeaders == null) {
24 | responseHeaders = new LinkedHashMap<>();
25 | for (Header header : this.response.getAllHeaders()) {
26 | responseHeaders.put(header.getName(), header.getValue());
27 | }
28 | }
29 | return this.responseHeaders;
30 | }
31 |
32 | @Override
33 | public InputStream getBody() throws IOException {
34 | return response.getEntity().getContent();
35 | }
36 |
37 | @Override
38 | public int getStatusCode() {
39 | return this.response.getStatusLine().getStatusCode();
40 | }
41 |
42 | @Override
43 | public void close() throws IOException {
44 | if (this.response != null) {
45 | HttpClientUtils.closeQuietly(response);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/process/Parameter.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.process;
2 |
3 | import com.github.weaksloth.dolphins.remote.RequestHttpEntity;
4 | import com.github.weaksloth.dolphins.util.JacksonUtils;
5 | import lombok.AllArgsConstructor;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 | import lombok.experimental.Accessors;
9 |
10 | /**
11 | * task parameter or global parameter
12 | *
13 | * doc
15 | * in official website
16 | */
17 | @Data
18 | @Accessors(chain = true)
19 | @NoArgsConstructor
20 | @AllArgsConstructor
21 | public class Parameter {
22 |
23 | private String prop;
24 |
25 | private String value;
26 |
27 | /** in or out */
28 | private String direct;
29 |
30 | /** VARCHAR,INTEGER,LONG.... */
31 | private String type;
32 |
33 | /**
34 | * get default global parameter instance
35 | *
36 | * @return global parameter instance
37 | */
38 | public static Parameter getGlobal() {
39 | Parameter parameter = new Parameter();
40 | parameter.setDirect("IN");
41 | parameter.setProp("VARCHAR");
42 | return parameter;
43 | }
44 |
45 | /**
46 | * must rewrite,then {@link RequestHttpEntity#bodyToMap()} can transfer object to json string
47 | *
48 | * @return object json string
49 | */
50 | @Override
51 | public String toString() {
52 | return JacksonUtils.toJSONString(this);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/ListenerEventType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import lombok.Getter;
6 |
7 | @Getter
8 | public enum ListenerEventType {
9 | SERVER_DOWN(0, "SERVER_DOWN"),
10 | PROCESS_DEFINITION_CREATED(1, "PROCESS_DEFINITION_CREATED"),
11 | PROCESS_DEFINITION_UPDATED(2, "PROCESS_DEFINITION_UPDATED"),
12 | PROCESS_DEFINITION_DELETED(3, "PROCESS_DEFINITION_DELETED"),
13 | PROCESS_START(4, "PROCESS_START"),
14 | PROCESS_END(5, "PROCESS_INSTANCE_END"),
15 | PROCESS_FAIL(6, "PROCESS_FAIL"),
16 | TASK_START(10, "TASK_START"),
17 | TASK_END(11, "TASK_END"),
18 | TASK_FAIL(12, "TASK_FAIL");
19 |
20 | private static final Map CODE_MAP = new HashMap<>();
21 |
22 | static {
23 | for (ListenerEventType listenerEventType : ListenerEventType.values()) {
24 | CODE_MAP.put(listenerEventType.getCode(), listenerEventType);
25 | }
26 | }
27 |
28 | private final int code;
29 | private final String descp;
30 |
31 | ListenerEventType(int code, String descp) {
32 | this.code = code;
33 | this.descp = descp;
34 | }
35 |
36 | public static ListenerEventType of(int code) {
37 | ListenerEventType listenerEventType = CODE_MAP.get(code);
38 | if (listenerEventType == null) {
39 | throw new IllegalArgumentException(
40 | String.format("The task execution status code: %s is invalid", code));
41 | }
42 | return listenerEventType;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/AuthorizationType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | /** Authorization type */
4 | public enum AuthorizationType {
5 |
6 | /**
7 | * 0 RESOURCE_FILE_ID; 1 RESOURCE_FILE_NAME; 2 UDF_FILE; 3 DATASOURCE; 4 UDF; 5 PROJECTS; 6
8 | * WORKER_GROUP; 7 ALERT_GROUP; 8 ENVIRONMENT; 9 ACCESS_TOKEN; 10 QUEUE; 11 DATA_ANALYSIS; 12
9 | * K8S_NAMESPACE; 13 MONITOR; 14 ALERT_PLUGIN_INSTANCE; 15 TENANT; 16 USER; 17 Data_Quality;
10 | */
11 | @Deprecated
12 | RESOURCE_FILE_ID(0, "resource file id"),
13 | @Deprecated
14 | RESOURCE_FILE_NAME(1, "resource file name"),
15 | @Deprecated
16 | UDF_FILE(2, "udf file"),
17 | DATASOURCE(3, "data source"),
18 | UDF(4, "udf function"),
19 | PROJECTS(5, "projects"),
20 | WORKER_GROUP(6, "worker group"),
21 | ALERT_GROUP(7, "alert group"),
22 | ENVIRONMENT(8, "environment"),
23 | ACCESS_TOKEN(9, "access token"),
24 | QUEUE(10, "queue"),
25 | DATA_ANALYSIS(11, "data analysis"),
26 | K8S_NAMESPACE(12, "k8s namespace"),
27 | MONITOR(13, "monitor"),
28 | ALERT_PLUGIN_INSTANCE(14, "alert plugin instance"),
29 | TENANT(15, "tenant"),
30 | DATA_QUALITY(16, "data quality"),
31 | TASK_GROUP(17, "task group"),
32 | ;
33 |
34 | AuthorizationType(int code, String descp) {
35 | this.code = code;
36 | this.descp = descp;
37 | }
38 |
39 | private final int code;
40 | private final String descp;
41 |
42 | public int getCode() {
43 | return code;
44 | }
45 |
46 | public String getDescp() {
47 | return descp;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/tenant/TenantTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.tenant;
2 |
3 | import com.github.weaksloth.dolphins.BaseTest;
4 | import java.util.List;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | public class TenantTest extends BaseTest {
9 |
10 | public static final String TENANT_CODE = "yhmi";
11 |
12 | @Test
13 | public void testCreateTenant() {
14 | TenantDefineParam createParam = new TenantDefineParam();
15 | createParam.setTenantCode(TENANT_CODE).setDescription("create by dolphin scheduler api");
16 | TenantInfoResp tenantInfoResp = getClient().opsForTenant().create(createParam);
17 | System.out.println(tenantInfoResp);
18 | Assert.assertEquals(TENANT_CODE, tenantInfoResp.getTenantCode());
19 | }
20 |
21 | @Test
22 | public void testUpdateTenant() {
23 | long tenantId = getClient().opsForTenant().page(null, null, TENANT_CODE).get(0).getId();
24 | TenantDefineParam updateParam = new TenantDefineParam();
25 | updateParam.setTenantCode(TENANT_CODE).setDescription("update by dolphin scheduler");
26 | Assert.assertTrue(getClient().opsForTenant().update(tenantId, updateParam));
27 | }
28 |
29 | @Test
30 | public void testPageTenant() {
31 | List page = getClient().opsForTenant().page(null, null, "");
32 | page.forEach(System.out::println);
33 | }
34 |
35 | @Test
36 | public void testDeleteTenant() {
37 | long tenantId = getClient().opsForTenant().page(null, null, TENANT_CODE).get(0).getId();
38 | Assert.assertTrue(getClient().opsForTenant().delete(tenantId));
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/ProcessExecutionTypeEnum.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 |
5 | public enum ProcessExecutionTypeEnum {
6 | PARALLEL(0, "parallel"),
7 | SERIAL_WAIT(1, "serial wait"),
8 | SERIAL_DISCARD(2, "serial discard"),
9 | SERIAL_PRIORITY(3, "serial priority");
10 |
11 | ProcessExecutionTypeEnum(int code, String descp) {
12 | this.code = code;
13 | this.descp = descp;
14 | }
15 |
16 | private final int code;
17 | private final String descp;
18 |
19 | private static HashMap EXECUTION_STATUS_MAP = new HashMap<>();
20 |
21 | static {
22 | for (ProcessExecutionTypeEnum executionType : ProcessExecutionTypeEnum.values()) {
23 | EXECUTION_STATUS_MAP.put(executionType.code, executionType);
24 | }
25 | }
26 |
27 | public boolean typeIsSerial() {
28 | return this != PARALLEL;
29 | }
30 |
31 | public boolean typeIsSerialWait() {
32 | return this == SERIAL_WAIT;
33 | }
34 |
35 | public boolean typeIsSerialDiscard() {
36 | return this == SERIAL_DISCARD;
37 | }
38 |
39 | public boolean typeIsSerialPriority() {
40 | return this == SERIAL_PRIORITY;
41 | }
42 |
43 | public int getCode() {
44 | return code;
45 | }
46 |
47 | public String getDescp() {
48 | return descp;
49 | }
50 |
51 | public static ProcessExecutionTypeEnum of(int executionType) {
52 | if (EXECUTION_STATUS_MAP.containsKey(executionType)) {
53 | return EXECUTION_STATUS_MAP.get(executionType);
54 | }
55 | throw new IllegalArgumentException("invalid status : " + executionType);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/handler/ResponseHandler.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote.handler;
2 |
3 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
4 | import com.github.weaksloth.dolphins.remote.TypeReferenceHttpResult;
5 | import com.github.weaksloth.dolphins.remote.response.HttpClientResponse;
6 | import com.github.weaksloth.dolphins.util.JacksonUtils;
7 | import com.google.common.base.Charsets;
8 | import com.google.common.io.CharStreams;
9 | import java.io.InputStream;
10 | import java.io.InputStreamReader;
11 | import org.apache.http.HttpStatus;
12 |
13 | public class ResponseHandler {
14 |
15 | private Class responseType;
16 |
17 | public final void setResponseType(Class responseType) {
18 | this.responseType = responseType;
19 | }
20 |
21 | public final HttpRestResult handle(HttpClientResponse response) throws Exception {
22 | if (HttpStatus.SC_BAD_REQUEST < response.getStatusCode()) {
23 | return handleError(response);
24 | }
25 | return convertResult(response, this.responseType);
26 | }
27 |
28 | private HttpRestResult handleError(HttpClientResponse response) throws Exception {
29 | String message =
30 | CharStreams.toString(new InputStreamReader(response.getBody(), Charsets.UTF_8));
31 | return new HttpRestResult<>(response.getStatusCode(), message, null, false, true);
32 | }
33 |
34 | public HttpRestResult convertResult(HttpClientResponse response, Class responseType)
35 | throws Exception {
36 | InputStream body = response.getBody();
37 | return JacksonUtils.parseObject(body, new TypeReferenceHttpResult<>(responseType));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/task/DataxTask.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.task;
2 |
3 | import com.github.weaksloth.dolphins.enums.DbTypeEnum;
4 | import java.util.Collections;
5 | import java.util.List;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | /** reference: org.apache.dolphinscheduler.plugin.task.datax.DataxParameters */
11 | @EqualsAndHashCode(callSuper = true)
12 | @Data
13 | @Accessors(chain = true)
14 | public class DataxTask extends AbstractTask {
15 |
16 | /**
17 | * do not custom config
18 | *
19 | * 0: write sql, dolphin scheduler will construct datax config
20 | *
21 | *
1: give datax config by yourself
22 | */
23 | private Integer customConfig = 0;
24 |
25 | /** if customConfig eq 1 ,then json is usable */
26 | private String json;
27 |
28 | /** datasource type,{@link DbTypeEnum#name()} */
29 | private String dsType;
30 |
31 | /** datasource id */
32 | private Long dataSource;
33 |
34 | /** target datasource type */
35 | private String dtType;
36 |
37 | /** target datasource id */
38 | private Long dataTarget;
39 |
40 | /** the sql will be executed in "dataSource" and write to "dataTarget" */
41 | private String sql;
42 |
43 | /** target table */
44 | private String targetTable;
45 |
46 | private Integer jobSpeedByte = 0;
47 | private Integer jobSpeedRecord = 1000;
48 | private List preStatements = Collections.emptyList();
49 | private List postStatements = Collections.emptyList();
50 | private Integer xms = 1;
51 | private Integer xmx = 1;
52 |
53 | @Override
54 | public String getTaskType() {
55 | return "DATAX";
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/process/TaskDefinition.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.process;
2 |
3 | import com.github.weaksloth.dolphins.remote.RequestHttpEntity;
4 | import com.github.weaksloth.dolphins.task.AbstractTask;
5 | import com.github.weaksloth.dolphins.util.JacksonUtils;
6 | import lombok.Data;
7 | import lombok.experimental.Accessors;
8 |
9 | @Data
10 | @Accessors(chain = true)
11 | public class TaskDefinition {
12 |
13 | private Long code;
14 |
15 | private Integer version;
16 |
17 | /** the task node's name */
18 | private String name;
19 |
20 | /** the task node's description */
21 | private String description;
22 |
23 | /** get from {@link AbstractTask#getTaskType()} */
24 | private String taskType;
25 |
26 | private AbstractTask taskParams;
27 |
28 | /** NO:the node will not execute;YES:the node will execute,default is YES */
29 | private String flag;
30 |
31 | private String taskPriority;
32 |
33 | private String workerGroup;
34 |
35 | private String failRetryTimes;
36 |
37 | private String failRetryInterval;
38 |
39 | private String timeoutFlag;
40 |
41 | private String timeoutNotifyStrategy;
42 |
43 | private Integer timeout = 0;
44 |
45 | private String delayTime = "0";
46 |
47 | private Integer environmentCode = -1;
48 |
49 | private String taskExecuteType;
50 |
51 | private Integer cpuQuota = -1;
52 |
53 | private Long memoryMax = -1L;
54 |
55 | /** YES, NO * */
56 | private String isCache = "NO";
57 |
58 | /**
59 | * must rewrite,then {@link RequestHttpEntity#bodyToMap()} can transfer object to json string
60 | *
61 | * @return object json string
62 | */
63 | @Override
64 | public String toString() {
65 | return JacksonUtils.toJSONString(this);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/Query.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.net.URLEncoder;
5 | import java.nio.charset.StandardCharsets;
6 | import java.util.LinkedHashMap;
7 | import java.util.Map;
8 | import java.util.Set;
9 |
10 | /** query param for get option */
11 | public class Query {
12 |
13 | private Map params;
14 |
15 | public Query() {
16 | params = new LinkedHashMap<>();
17 | }
18 |
19 | public Query addParam(String key, String value) {
20 | params.put(key, value);
21 | return this;
22 | }
23 |
24 | public Query build() {
25 | return this;
26 | }
27 |
28 | public Object getValue(String key) {
29 | return params.get(key);
30 | }
31 |
32 | public boolean isEmpty() {
33 | return params.isEmpty();
34 | }
35 |
36 | /**
37 | * Print query as a http url param string. Like K=V&K=V.
38 | *
39 | * @return http url param string
40 | */
41 | public String toQueryUrl() {
42 | StringBuilder urlBuilder = new StringBuilder();
43 | Set> entrySet = params.entrySet();
44 | int i = entrySet.size();
45 | for (Map.Entry entry : entrySet) {
46 | try {
47 | if (null != entry.getValue()) {
48 | urlBuilder
49 | .append(entry.getKey())
50 | .append('=')
51 | .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.displayName()));
52 | if (i > 1) {
53 | urlBuilder.append('&');
54 | }
55 | }
56 | i--;
57 | } catch (UnsupportedEncodingException e) {
58 | throw new RuntimeException(e);
59 | }
60 | }
61 |
62 | return urlBuilder.toString();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/project/ProjectTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.project;
2 |
3 | import com.github.weaksloth.dolphins.BaseTest;
4 | import org.junit.Assert;
5 | import org.junit.Test;
6 |
7 | public class ProjectTest extends BaseTest {
8 |
9 | private static final String PROJECT_NAME = "test_project";
10 |
11 | @Test
12 | public void testCreateProject() {
13 |
14 | ProjectCreateParam param = new ProjectCreateParam();
15 | param.setProjectName(PROJECT_NAME).setDescription("created by dolphinscheduler java sdk");
16 | ProjectInfoResp projectInfoResp = getClient().opsForProject().create(param);
17 | System.out.println(projectInfoResp);
18 | Assert.assertEquals(PROJECT_NAME, projectInfoResp.getName());
19 | }
20 |
21 | @Test
22 | public void testListProject() {
23 | getClient().opsForProject().page(null, null, null).forEach(System.out::println);
24 | }
25 |
26 | @Test
27 | public void testUpdateProject() {
28 | ProjectInfoResp projectInfo = getClient().opsForProject().page(null, null, PROJECT_NAME).get(0);
29 | ProjectUpdateParam updateParam = new ProjectUpdateParam();
30 | String newDescription = "updated by dolphinscheduler java sdk";
31 | updateParam
32 | .setProjectName(PROJECT_NAME)
33 | .setProjectCode(projectInfo.getCode())
34 | .setUserName(projectInfo.getUserName())
35 | .setDescription(newDescription);
36 | ProjectInfoResp newProjectInfo = getClient().opsForProject().update(updateParam);
37 | Assert.assertEquals(newDescription, newProjectInfo.getDescription());
38 | }
39 |
40 | @Test
41 | public void testDeleteProject() {
42 | // get test project code
43 | long code = getClient().opsForProject().page(null, null, PROJECT_NAME).get(0).getCode();
44 | getClient().opsForProject().delete(code);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/core/DolphinClientConstant.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.core;
2 |
3 | public class DolphinClientConstant {
4 |
5 | public static class Page {
6 | public static final Integer DEFAULT_PAGE = 1;
7 | public static final Integer DEFAULT_SIZE = 10;
8 | }
9 |
10 | public static class LogLimit {
11 | public static final Integer DEFAULT_SKIP = 0;
12 | public static final Integer DEFAULT_LIMIT = 50;
13 | }
14 |
15 | public static final String OFFLINE_RELEASE_STATE = "OFFLINE"; // 工作流下线状态
16 | public static final String ONLINE_RELEASE_STATE = "ONLINE"; // 工作流上线状态
17 |
18 | /** the same with org.apache.dolphinscheduler.api.enums.ExecuteType */
19 | public static class ExecuteType {
20 | public static final String RE_RUN = "REPEAT_RUNNING";
21 | public static final String STOP = "STOP";
22 | public static final String PAUSE = "PAUSE";
23 | }
24 |
25 | public static class HttpTask {
26 | public static final String HTTP_PARAMETER_TYPE_PARAMETER = "PARAMETER";
27 | public static final String HTTP_PARAMETER_TYPE_BODY = "BODY";
28 | public static final String HTTP_PARAMETER_TYPE_HEADERS = "HEADERS";
29 |
30 | public static final String HTTP_METHOD_GET = "GET";
31 | public static final String HTTP_METHOD_POST = "POST";
32 | public static final String HTTP_METHOD_PUT = "PUT";
33 | }
34 |
35 | public static class TaskType {
36 | public static final String DATAX = "DATAX";
37 | public static final String HTTP = "HTTP";
38 | public static final String CONDITION = "CONDITIONS";
39 | public static final String SHELL = "SHELL";
40 | }
41 |
42 | public static class Resource {
43 | public static final String TYPE_FILE = "FILE";
44 | public static final String TYPE_UDF = "UDF";
45 | public static final String DEFAULT_PID_FILE = "-1";
46 | public static final String DEFAULT_CURRENT_DIR = "/";
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/task/SparkTask.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.task;
2 |
3 | import com.github.weaksloth.dolphins.process.Parameter;
4 | import java.util.Collections;
5 | import java.util.List;
6 | import lombok.Data;
7 | import lombok.EqualsAndHashCode;
8 | import lombok.experimental.Accessors;
9 |
10 | /** reference: org.apache.dolphinscheduler.plugin.task.spark.SparkParameters */
11 | @EqualsAndHashCode(callSuper = true)
12 | @Data
13 | @Accessors(chain = true)
14 | public class SparkTask extends AbstractTask {
15 |
16 | private String appName;
17 | private TaskResource mainJar;
18 | private String mainClass;
19 | private String mainArgs;
20 |
21 | /** optional value:cluster,client,local */
22 | private String deployMode;
23 |
24 | // spark task resource
25 | private Integer driverCores;
26 | private String driverMemory;
27 | private Integer numExecutors;
28 | private Integer executorCores;
29 | private String executorMemory;
30 |
31 | private String others;
32 |
33 | /** yarn queue */
34 | private String queue;
35 |
36 | /** optional value:JAVA,SCALA,PYTHON,SQL */
37 | private String programType;
38 |
39 | /** spark sql script if programType is SQL */
40 | private String rawScript;
41 |
42 | /** optional value:SPARK2,SPARK1 */
43 | private String sparkVersion;
44 |
45 | private List localParams = Collections.emptyList();
46 |
47 | private List resourceList = Collections.emptyList();
48 |
49 | public static SparkTask newV2Instance() {
50 | return new SparkTask().setSparkVersion("SPARK2");
51 | }
52 |
53 | public SparkTask inClientMode() {
54 | this.deployMode = "client";
55 | return this;
56 | }
57 |
58 | public SparkTask inClusterMode() {
59 | this.deployMode = "cluster";
60 | return this;
61 | }
62 |
63 | @Override
64 | public String getTaskType() {
65 | return "SPARK";
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/BaseHttpMethod.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote;
2 |
3 | import com.google.common.base.Strings;
4 | import org.apache.http.client.methods.*;
5 |
6 | public enum BaseHttpMethod {
7 | GET(HttpMethod.GET) {
8 | @Override
9 | protected HttpRequestBase createRequest(String url) {
10 | return new HttpGet(url);
11 | }
12 | },
13 |
14 | POST(HttpMethod.POST) {
15 | @Override
16 | protected HttpRequestBase createRequest(String url) {
17 | return new HttpPost(url);
18 | }
19 | },
20 |
21 | PUT(HttpMethod.PUT) {
22 | @Override
23 | protected HttpRequestBase createRequest(String url) {
24 | return new HttpPut(url);
25 | }
26 | },
27 |
28 | PATCH(HttpMethod.PATCH) {
29 | @Override
30 | protected HttpRequestBase createRequest(String url) {
31 | return new HttpPatch(url);
32 | }
33 | },
34 |
35 | DELETE(HttpMethod.DELETE) {
36 | @Override
37 | protected HttpRequestBase createRequest(String url) {
38 | return new HttpDelete(url);
39 | }
40 | };
41 |
42 | private String name;
43 |
44 | BaseHttpMethod(String name) {
45 | this.name = name;
46 | }
47 |
48 | public HttpRequestBase init(String url) {
49 | return createRequest(url);
50 | }
51 |
52 | protected HttpRequestBase createRequest(String url) {
53 | throw new UnsupportedOperationException();
54 | }
55 |
56 | /**
57 | * get base http method by name
58 | *
59 | * @param name
60 | * @return
61 | */
62 | public static BaseHttpMethod of(String name) {
63 | if (!Strings.isNullOrEmpty(name)) {
64 | for (BaseHttpMethod method : BaseHttpMethod.values()) {
65 | if (name.toLowerCase().equals(method.name.toLowerCase())) {
66 | return method;
67 | }
68 | }
69 | }
70 | throw new IllegalArgumentException("Unsupported http method : " + name);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/HttpClientFactory.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote;
2 |
3 | import com.github.weaksloth.dolphins.remote.request.DefaultHttpClientRequest;
4 | import com.google.common.base.Strings;
5 | import org.apache.http.client.config.RequestConfig;
6 | import org.apache.http.impl.client.HttpClients;
7 | import org.apache.http.protocol.RequestContent;
8 |
9 | /** the factory to create http client(rest template) */
10 | public class HttpClientFactory {
11 |
12 | public static final String HTTP_CLIENT_APACHE = "apache";
13 | public static final String HTTP_CLIENT_SPRING = "spring";
14 |
15 | /**
16 | * get rest template to operate dolphin scheduler
17 | *
18 | * @param type use HttpClientFactory.HTTP_CLIENT_APACHE and HttpClientFactory.HTTP_CLIENT_SPRING
19 | * @return
20 | */
21 | public DolphinsRestTemplate getRestTemplate(String type) {
22 | if (Strings.isNullOrEmpty(type)) {
23 | throw new IllegalArgumentException("type is null.");
24 | }
25 | switch (type) {
26 | case HTTP_CLIENT_APACHE:
27 | return getApacheRestTemplate();
28 | case HTTP_CLIENT_SPRING:
29 | return getSpringRestTemplate();
30 | default:
31 | throw new UnsupportedOperationException("now only support apache and spring.");
32 | }
33 | }
34 |
35 | /**
36 | * get rest template based on apache http client
37 | *
38 | * @return
39 | */
40 | public DolphinsRestTemplate getApacheRestTemplate() {
41 |
42 | final RequestConfig defaultConfig = RequestConfig.custom().build();
43 |
44 | return new DolphinsRestTemplate(
45 | new DefaultHttpClientRequest(
46 | HttpClients.custom()
47 | .addInterceptorLast(new RequestContent(true))
48 | .setDefaultRequestConfig(defaultConfig)
49 | .build(),
50 | defaultConfig));
51 | }
52 |
53 | // TODO
54 | public DolphinsRestTemplate getSpringRestTemplate() {
55 | throw new UnsupportedOperationException();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/insatnce/ProcessInstanceTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.insatnce;
2 |
3 | import com.github.weaksloth.dolphins.BaseTest;
4 | import com.github.weaksloth.dolphins.enums.*;
5 | import com.github.weaksloth.dolphins.instance.ProcessInstanceCreateParam;
6 | import org.junit.Assert;
7 | import org.junit.Test;
8 |
9 | public class ProcessInstanceTest extends BaseTest {
10 |
11 | public static final Long PROCESS_DEFINITION_CODE = 11386905142912L;
12 |
13 | /** the workflow must in online state,otherwise will cause error */
14 | @Test
15 | public void testStartInstance() {
16 |
17 | ProcessInstanceCreateParam startParam = new ProcessInstanceCreateParam();
18 | startParam
19 | .setProcessDefinitionCode(PROCESS_DEFINITION_CODE)
20 | .setScheduleTime("")
21 | .setFailureStrategy(FailureStrategy.CONTINUE.toString())
22 | .setWarningType(WarningType.NONE.toString())
23 | .setWarningGroupId(0L)
24 | .setExecType("")
25 | .setStartNodeList("")
26 | .setTaskDependType(TaskDependType.TASK_POST.toString())
27 | .setRunMode(RunMode.RUN_MODE_SERIAL.toString())
28 | .setProcessInstancePriority(Priority.MEDIUM.toString())
29 | .setWorkerGroup("default")
30 | .setEnvironmentCode("")
31 | .setStartParams("")
32 | .setExpectedParallelismNumber("")
33 | .setDryRun(0);
34 | Assert.assertTrue(getClient().opsForProcessInst().start(projectCode, startParam));
35 | }
36 |
37 | @Test
38 | public void testReRun() {
39 | Long instanceId = 31L;
40 | Assert.assertTrue(getClient().opsForProcessInst().reRun(projectCode, instanceId));
41 | }
42 |
43 | @Test
44 | public void testPage() {
45 | getClient()
46 | .opsForProcessInst()
47 | .page(null, null, projectCode, PROCESS_DEFINITION_CODE)
48 | .forEach(System.out::println);
49 | }
50 |
51 | @Test
52 | public void testDelete() {
53 | Long instanceId = 31L;
54 | Assert.assertTrue(getClient().opsForProcessInst().delete(projectCode, instanceId));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/process/ProcessDefineResp.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.process;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import java.util.Date;
5 | import java.util.List;
6 | import java.util.Map;
7 | import lombok.Data;
8 |
9 | /** define process response,copied from org.apache.dolphinscheduler.dao.entity.ProcessDefinition */
10 | @Data
11 | public class ProcessDefineResp {
12 |
13 | /** id */
14 | private int id;
15 |
16 | /** code */
17 | private long code;
18 |
19 | /** name */
20 | private String name;
21 |
22 | /** version */
23 | private int version;
24 |
25 | /** release state : online/offline */
26 | private String releaseState;
27 |
28 | /** project code */
29 | private long projectCode;
30 |
31 | /** description */
32 | private String description;
33 |
34 | /** user defined parameters */
35 | private String globalParams;
36 |
37 | /** user defined parameter list */
38 | private List globalParamList;
39 |
40 | /** user define parameter map */
41 | private Map globalParamMap;
42 |
43 | /** create time */
44 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
45 | private Date createTime;
46 |
47 | /** update time */
48 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
49 | private Date updateTime;
50 |
51 | /** process is valid: yes/no */
52 | private String flag;
53 |
54 | /** process user id */
55 | private int userId;
56 |
57 | /** user name */
58 | private String userName;
59 |
60 | /** project name */
61 | private String projectName;
62 |
63 | /** locations array for web */
64 | private String locations;
65 |
66 | /** schedule release state : online/offline */
67 | private String scheduleReleaseState;
68 |
69 | /** process warning time out. unit: minute */
70 | private int timeout;
71 |
72 | /** tenant id */
73 | private int tenantId;
74 |
75 | /** tenant code */
76 | private String tenantCode;
77 |
78 | /** modify user name */
79 | private String modifyBy;
80 |
81 | /** warningGroupId */
82 | private int warningGroupId;
83 |
84 | private String executionType;
85 | }
86 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/schedule/ScheduleTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.schedule;
2 |
3 | import com.github.weaksloth.dolphins.BaseTest;
4 | import java.util.List;
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | public class ScheduleTest extends BaseTest {
9 |
10 | public static final Long WORKFLOW_CODE = 11386905160832L;
11 |
12 | /** the workflow must in online state */
13 | @Test
14 | public void testCreate() {
15 | ScheduleDefineParam scheduleDefineParam = new ScheduleDefineParam();
16 | scheduleDefineParam
17 | .setProcessDefinitionCode(WORKFLOW_CODE)
18 | .setSchedule(
19 | new ScheduleDefineParam.Schedule()
20 | .setStartTime("2023-10-27 00:00:00")
21 | .setEndTime("2024-09-20 00:00:00")
22 | .setCrontab("0 0 * * * ? *"));
23 | ScheduleInfoResp scheduleInfoResp =
24 | getClient().opsForSchedule().create(projectCode, scheduleDefineParam);
25 | System.out.println(scheduleInfoResp);
26 | }
27 |
28 | @Test
29 | public void testGetByProject() {
30 | List resp =
31 | getClient().opsForSchedule().getByWorkflowCode(projectCode, WORKFLOW_CODE);
32 | System.out.println(resp);
33 | Assert.assertEquals(1, resp.size());
34 | }
35 |
36 | @Test
37 | public void testOnline() {
38 | List resp =
39 | getClient().opsForSchedule().getByWorkflowCode(projectCode, WORKFLOW_CODE);
40 | long id = resp.get(0).getId();
41 | Assert.assertTrue(getClient().opsForSchedule().online(projectCode, id));
42 | }
43 |
44 | @Test
45 | public void testOffline() {
46 | List resp =
47 | getClient().opsForSchedule().getByWorkflowCode(projectCode, WORKFLOW_CODE);
48 | long id = resp.get(0).getId();
49 | Assert.assertTrue(getClient().opsForSchedule().offline(projectCode, id));
50 | }
51 |
52 | @Test
53 | public void testDelete() {
54 | List resp =
55 | getClient().opsForSchedule().getByWorkflowCode(projectCode, WORKFLOW_CODE);
56 | long id = resp.get(0).getId();
57 | Assert.assertTrue(getClient().opsForSchedule().delete(projectCode, id));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/schedule/ScheduleInfoResp.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.schedule;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import java.util.Date;
6 | import lombok.Data;
7 | import lombok.experimental.Accessors;
8 |
9 | /** copied from org.apache.dolphinscheduler.dao.entity.Schedule */
10 | @Data
11 | @Accessors(chain = true)
12 | @JsonIgnoreProperties(ignoreUnknown = true)
13 | public class ScheduleInfoResp {
14 |
15 | private int id;
16 |
17 | /** process definition code */
18 | private long processDefinitionCode;
19 |
20 | /** process definition name */
21 | private String processDefinitionName;
22 |
23 | /** project name */
24 | private String projectName;
25 |
26 | /** schedule description */
27 | private String definitionDescription;
28 |
29 | /** schedule start time */
30 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
31 | private Date startTime;
32 |
33 | /** schedule end time */
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date endTime;
36 |
37 | /**
38 | * timezoneId
39 | *
40 | * see {@link java.util.TimeZone#getTimeZone(String)}
41 | */
42 | private String timezoneId;
43 |
44 | /** crontab expression */
45 | private String crontab;
46 |
47 | /** failure strategy */
48 | private String failureStrategy;
49 |
50 | /** warning type */
51 | private String warningType;
52 |
53 | /** create time */
54 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
55 | private Date createTime;
56 |
57 | /** update time */
58 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
59 | private Date updateTime;
60 |
61 | /** created user id */
62 | private int userId;
63 |
64 | /** created user name */
65 | private String userName;
66 |
67 | /** release state */
68 | private String releaseState;
69 |
70 | /** warning group id */
71 | private int warningGroupId;
72 |
73 | /** process instance priority */
74 | private String processInstancePriority;
75 |
76 | /** worker group */
77 | private String workerGroup;
78 |
79 | /** environment code */
80 | private Long environmentCode;
81 | }
82 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/datasource/DataSourceTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.datasource;
2 |
3 | import com.github.weaksloth.dolphins.BaseTest;
4 | import com.github.weaksloth.dolphins.enums.DbTypeEnum;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import org.junit.Assert;
9 | import org.junit.Test;
10 |
11 | public class DataSourceTest extends BaseTest {
12 |
13 | /** create datasource */
14 | @Test
15 | public void createDataSource() {
16 | DataSourceCreateParam dataSourceCreateParam = new DataSourceCreateParam();
17 | Map map = new HashMap<>();
18 | map.put("useSSL", "false");
19 | dataSourceCreateParam
20 | .setUserName("root")
21 | .setPassword("xxxxxx") // use your own db info
22 | .setDatabase("test")
23 | .setPort("3306")
24 | .setName("ds-create-test2")
25 | .setType(DbTypeEnum.MYSQL.name())
26 | .setHost("localhost")
27 | .setOther(map);
28 | Assert.assertTrue(getClient().opsForDataSource().create(dataSourceCreateParam));
29 | }
30 |
31 | /** list all datasource */
32 | @Test
33 | public void listDataSource() {
34 | System.out.println(getClient().opsForDataSource().list(null));
35 | }
36 |
37 | /** update datasource */
38 | @Test
39 | public void updateDataSource() {
40 | List dataSources = getClient().opsForDataSource().list(null);
41 | DataSourceUpdateParam dataSourceUpdateParam = new DataSourceUpdateParam();
42 | dataSourceUpdateParam
43 | .setId(dataSources.get(0).getId()) // this id from create
44 | .setUserName("root")
45 | .setPassword("xxxxxx")
46 | .setDatabase("test")
47 | .setPort("3306")
48 | .setName("ds-create-test")
49 | .setNote("this note is generate by update api")
50 | .setType(DbTypeEnum.MYSQL.name())
51 | .setHost("localhost");
52 | Assert.assertTrue(getClient().opsForDataSource().update(dataSourceUpdateParam));
53 | }
54 |
55 | @Test
56 | public void deleteDataSource() {
57 | List dataSources = getClient().opsForDataSource().list(null);
58 | Assert.assertTrue(getClient().opsForDataSource().delete(dataSources.get(0).getId()));
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/CommandType.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /** command types */
7 | public enum CommandType {
8 |
9 | /**
10 | * command types 0 start a new process 1 start a new process from current nodes 2 recover
11 | * tolerance fault process 3 recover suspended process 4 start process from failure task nodes 5
12 | * complement data 6 start a new process from scheduler 7 repeat running a process 8 pause a
13 | * process 9 stop a process 10 recover waiting thread 11 recover serial wait 12 start a task node
14 | * in a process instance
15 | */
16 | START_PROCESS(0, "start a new process"),
17 | START_CURRENT_TASK_PROCESS(1, "start a new process from current nodes"),
18 | RECOVER_TOLERANCE_FAULT_PROCESS(2, "recover tolerance fault process"),
19 | RECOVER_SUSPENDED_PROCESS(3, "recover suspended process"),
20 | START_FAILURE_TASK_PROCESS(4, "start process from failure task nodes"),
21 | COMPLEMENT_DATA(5, "complement data"),
22 | SCHEDULER(6, "start a new process from scheduler"),
23 | REPEAT_RUNNING(7, "repeat running a process"),
24 | PAUSE(8, "pause a process"),
25 | STOP(9, "stop a process"),
26 | RECOVER_WAITING_THREAD(10, "recover waiting thread"),
27 | RECOVER_SERIAL_WAIT(11, "recover serial wait"),
28 | EXECUTE_TASK(12, "start a task node in a process instance"),
29 | DYNAMIC_GENERATION(13, "dynamic generation"),
30 | ;
31 |
32 | CommandType(int code, String descp) {
33 | this.code = code;
34 | this.descp = descp;
35 | }
36 |
37 | private final int code;
38 | private final String descp;
39 |
40 | public int getCode() {
41 | return code;
42 | }
43 |
44 | public String getDescp() {
45 | return descp;
46 | }
47 |
48 | private static final Map COMMAND_TYPE_MAP = new HashMap<>();
49 |
50 | static {
51 | for (CommandType commandType : CommandType.values()) {
52 | COMMAND_TYPE_MAP.put(commandType.code, commandType);
53 | }
54 | }
55 |
56 | public static CommandType of(Integer status) {
57 | if (COMMAND_TYPE_MAP.containsKey(status)) {
58 | return COMMAND_TYPE_MAP.get(status);
59 | }
60 | throw new IllegalArgumentException("invalid status : " + status);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/task/HttpTask.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.task;
2 |
3 | import com.github.weaksloth.dolphins.process.Parameter;
4 | import com.github.weaksloth.dolphins.remote.RequestHttpEntity;
5 | import com.github.weaksloth.dolphins.util.JacksonUtils;
6 | import java.util.Collections;
7 | import java.util.List;
8 | import lombok.AllArgsConstructor;
9 | import lombok.Data;
10 | import lombok.EqualsAndHashCode;
11 | import lombok.NoArgsConstructor;
12 | import lombok.experimental.Accessors;
13 |
14 | @EqualsAndHashCode(callSuper = true)
15 | @Data
16 | @Accessors(chain = true)
17 | public class HttpTask extends AbstractTask {
18 |
19 | private List localParams = Collections.emptyList();
20 |
21 | /** http request param */
22 | private List httpParams = Collections.emptyList();
23 |
24 | /** http request url */
25 | private String url;
26 |
27 | /** http method, {@link com.github.weaksloth.dolphins.remote.HttpMethod} */
28 | private String httpMethod;
29 |
30 | private String httpCheckCondition; // STATUS_CODE_DEFAULT
31 | private String condition;
32 | private Integer connectTimeout = 60000;
33 | private Integer socketTimeout = 60000;
34 |
35 | @Override
36 | public String getTaskType() {
37 | return "HTTP";
38 | }
39 |
40 | @Data
41 | @Accessors(chain = true)
42 | @AllArgsConstructor
43 | @NoArgsConstructor
44 | public static class HttpParam {
45 | private String prop;
46 | private String value;
47 | private String httpParametersType;
48 |
49 | /** create http form param instance */
50 | public static HttpParam newForm() {
51 | return new HttpParam(null, null, "PARAMETER");
52 | }
53 |
54 | /** create http headers param instance */
55 | public static HttpParam newHeader() {
56 | return new HttpParam(null, null, "HEADERS");
57 | }
58 |
59 | /** create http body param instance */
60 | public static HttpParam newBody() {
61 | return new HttpParam(null, null, "BODY");
62 | }
63 |
64 | /**
65 | * must rewrite,then {@link RequestHttpEntity#bodyToMap()} can transfer object to json string
66 | *
67 | * @return object json string
68 | */
69 | @Override
70 | public String toString() {
71 | return JacksonUtils.toJSONString(this);
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/resource/ResourceTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.resource;
2 |
3 | import com.github.weaksloth.dolphins.BaseTest;
4 | import com.github.weaksloth.dolphins.core.DolphinClientConstant;
5 | import java.io.File;
6 | import java.util.List;
7 | import org.junit.Assert;
8 | import org.junit.Test;
9 |
10 | public class ResourceTest extends BaseTest {
11 |
12 | private final String fileName = "dophinsdk-create2";
13 | private final String suffix = "sh";
14 | private final String fullName =
15 | "file:/home/"
16 | + tenantCode
17 | + "/ds/upload/"
18 | + tenantCode
19 | + "/resources/"
20 | + fileName
21 | + "."
22 | + suffix;
23 |
24 | @Test
25 | public void testPage() {
26 | List list =
27 | getClient()
28 | .opsForResource()
29 | .page(null, null, DolphinClientConstant.Resource.DEFAULT_PID_FILE, "");
30 | list.forEach(System.out::println);
31 | }
32 |
33 | @Test
34 | public void testOnlineCreate() {
35 | ResourceCreateParam resourceCreateParam = new ResourceCreateParam();
36 | resourceCreateParam
37 | .setSuffix(suffix)
38 | .setFileName(fileName)
39 | .setContent("created by dolphin scheduler java sdk");
40 | Assert.assertTrue(getClient().opsForResource().onlineCreate(resourceCreateParam));
41 | }
42 |
43 | @Test
44 | public void testOnlineUpdate() {
45 | ResourceUpdateParam resourceUpdateParam = new ResourceUpdateParam();
46 | resourceUpdateParam
47 | .setTenantCode(tenantCode)
48 | .setFullName(fullName)
49 | .setContent("update by dolphin scheduler java sdk");
50 | Assert.assertTrue(getClient().opsForResource().onlineUpdate(resourceUpdateParam));
51 | }
52 |
53 | @Test
54 | public void testUploadFile() {
55 | ResourceUploadParam resourceUploadParam = new ResourceUploadParam();
56 | resourceUploadParam
57 | .setName("test_upload.txt")
58 | .setDescription("upload by dolphin scheduler java sdk")
59 | .setFile(new File("/home/chen/Documents/test_upload.txt"));
60 | Assert.assertTrue(getClient().opsForResource().upload(resourceUploadParam));
61 | }
62 |
63 | @Test
64 | public void delete() {
65 | Assert.assertTrue(getClient().opsForResource().delete(tenantCode, fullName));
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/process/ProcessDefineParam.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.process;
2 |
3 | import java.util.List;
4 | import lombok.Data;
5 | import lombok.experimental.Accessors;
6 |
7 | /**
8 | * dolphin scheduler define process param
9 | *
10 | * dolphin scheduler use post form type to create process,so in fact every attribute is string
11 | * type
12 | *
13 | *
but in order to develop easier,we use TaskLocation,TaskDefinition,TaskRelation object,and
14 | * rewrite toString method
15 | *
16 | *
so that,when begin to send request,we will transfer this object to json string
17 | */
18 | @Data
19 | @Accessors(chain = true)
20 | public class ProcessDefineParam {
21 |
22 | public static final String EXECUTION_TYPE_PARALLEL = "PARALLEL";
23 | public static final String EXECUTION_TYPE_SERIAL_WAIT = "SERIAL_WAIT";
24 | public static final String EXECUTION_TYPE_SERIAL_DISCARD = "SERIAL_DISCARD";
25 | public static final String EXECUTION_TYPE_SERIAL_PRIORITY = "SERIAL_PRIORITY";
26 |
27 | /** workflow name */
28 | private String name;
29 |
30 | /** location */
31 | private List locations;
32 |
33 | private List taskDefinitionJson;
34 |
35 | private List taskRelationJson;
36 |
37 | /** tenant code */
38 | private String tenantCode;
39 |
40 | /** desc for workflow */
41 | private String description;
42 |
43 | /**
44 | * PARALLEL,SERIAL_WAIT,SERIAL_DISCARD,SERIAL_PRIORITY
45 | *
46 | * @see org.apache.dolphinscheduler.common.enums.ProcessExecutionTypeEnum
47 | */
48 | private String executionType;
49 |
50 | /** global params */
51 | private List globalParams;
52 |
53 | private String timeout;
54 |
55 | public static ProcessDefineParam newParallelInstance() {
56 | return new ProcessDefineParam().setExecutionType(EXECUTION_TYPE_PARALLEL);
57 | }
58 |
59 | public static ProcessDefineParam newSerialWaitInstance() {
60 | return new ProcessDefineParam().setExecutionType(EXECUTION_TYPE_SERIAL_WAIT);
61 | }
62 |
63 | public static ProcessDefineParam newSerialDiscardInstance() {
64 | return new ProcessDefineParam().setExecutionType(EXECUTION_TYPE_SERIAL_DISCARD);
65 | }
66 |
67 | public static ProcessDefineParam newSerialPriorityInstance() {
68 | return new ProcessDefineParam().setExecutionType(EXECUTION_TYPE_SERIAL_PRIORITY);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/RequestHttpEntity.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote;
2 |
3 | import com.github.weaksloth.dolphins.util.JacksonUtils;
4 | import java.lang.reflect.Field;
5 | import java.util.LinkedHashMap;
6 | import java.util.Map;
7 | import java.util.Objects;
8 | import java.util.Optional;
9 | import lombok.Data;
10 | import lombok.extern.slf4j.Slf4j;
11 |
12 | @Data
13 | @Slf4j
14 | public class RequestHttpEntity {
15 |
16 | private Header header;
17 |
18 | private Query query;
19 |
20 | private Object body;
21 |
22 | public RequestHttpEntity() {}
23 |
24 | public RequestHttpEntity(Header header, Query query) {
25 | this.header = header;
26 | this.query = query;
27 | }
28 |
29 | public RequestHttpEntity(Header header, Query query, Object body) {
30 | this.header = header;
31 | this.query = query;
32 | this.body = body;
33 | }
34 |
35 | public RequestHttpEntity(Header header, Object body) {
36 | this.header = header;
37 | this.body = body;
38 | }
39 |
40 | /**
41 | * cast object to map when the object is instance of map
42 | *
43 | * @return
44 | */
45 | public Map castBodyToMap() {
46 | if (ifBodyIsMap()) {
47 | return (Map) body;
48 | }
49 | throw new UnsupportedOperationException(
50 | "the body is not instance of map,do not use this method");
51 | }
52 |
53 | /**
54 | * judge if body instance of map
55 | *
56 | * @return
57 | */
58 | public boolean ifBodyIsMap() {
59 | return body instanceof Map;
60 | }
61 |
62 | /**
63 | * param object to json string
64 | *
65 | * @return
66 | */
67 | public String bodyToJson() {
68 | return JacksonUtils.toJSONString(this.body);
69 | }
70 |
71 | /**
72 | * param object to map by reflect
73 | *
74 | * @return map
75 | */
76 | public Map bodyToMap() {
77 | if (Objects.isNull(body)) {
78 | return null;
79 | }
80 |
81 | Map map = new LinkedHashMap<>();
82 | Field[] declaredFields = body.getClass().getDeclaredFields();
83 | for (Field field : declaredFields) {
84 | field.setAccessible(true);
85 | try {
86 | Optional.ofNullable(field.get(body)).ifPresent(value -> map.put(field.getName(), value));
87 | } catch (IllegalAccessException e) {
88 | log.error("object to map fail", e);
89 | }
90 | }
91 | return map;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/util/TaskLocationUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.util;
2 |
3 | import com.github.weaksloth.dolphins.process.TaskLocation;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | /** utils for node in dag graph's location */
8 | public class TaskLocationUtils {
9 |
10 | /**
11 | * this method is used for graph node get task location one by one,such as
12 | * (100,200),(300,200),(500,200)
13 | *
14 | * @param taskCodes task codes
15 | * @return {@link List}
16 | */
17 | public static List horizontalLocation(Long... taskCodes) {
18 | int beginX = 100;
19 | int y = 100;
20 | int xStep = 300;
21 | return horizontalLocation(beginX, y, xStep, taskCodes);
22 | }
23 |
24 | /**
25 | * this method is used for graph node get task location with custom x,y,step one by one,such as
26 | * (beginX,y),(beginX+step,y)....
27 | *
28 | * @param beginX location of begin x
29 | * @param xStep step of x
30 | * @param y location of y
31 | * @param taskCodes task codes
32 | * @return {@link List}
33 | */
34 | public static List horizontalLocation(
35 | int beginX, int y, int xStep, Long... taskCodes) {
36 | List list = new ArrayList<>();
37 | for (Long taskCode : taskCodes) {
38 | list.add(new TaskLocation(taskCode, beginX, y));
39 | beginX += xStep;
40 | }
41 | return list;
42 | }
43 |
44 | /**
45 | * this method is used for graph node get task location one by one,such as
46 | * (100,100),(100,300),(100,500)
47 | *
48 | * @param taskCodes task codes
49 | * @return {@link List}
50 | */
51 | public static List verticalLocation(Long... taskCodes) {
52 | int x = 100;
53 | int beginY = 100;
54 | int yStep = 300;
55 | return verticalLocation(x, beginY, yStep, taskCodes);
56 | }
57 |
58 | /**
59 | * @param x location of x
60 | * @param beginY location of begin y
61 | * @param yStep step of y
62 | * @param taskCodes task codes
63 | * @return {@link List}
64 | */
65 | public static List verticalLocation(
66 | int x, int beginY, int yStep, Long... taskCodes) {
67 | List list = new ArrayList<>();
68 | for (Long taskCode : taskCodes) {
69 | list.add(new TaskLocation(taskCode, x, beginY));
70 | beginY += yStep;
71 | }
72 | return list;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/Header.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote;
2 |
3 | import com.google.common.base.Strings;
4 | import com.google.common.net.HttpHeaders;
5 | import com.google.common.net.MediaType;
6 | import java.nio.charset.StandardCharsets;
7 | import java.util.Iterator;
8 | import java.util.LinkedHashMap;
9 | import java.util.Map;
10 |
11 | public class Header {
12 |
13 | private static final String DEFAULT_CHARSET = "UTF-8";
14 |
15 | private static final Header EMPTY = Header.newInstance();
16 |
17 | private Map header;
18 |
19 | private Header() {
20 | header = new LinkedHashMap<>();
21 | addParam(HttpHeaders.ACCEPT_CHARSET, DEFAULT_CHARSET);
22 | addParam(HttpHeaders.ACCEPT, MediaType.JSON_UTF_8.toString());
23 | addParam(HttpHeaders.CONTENT_TYPE, MediaType.FORM_DATA.toString());
24 | }
25 |
26 | public static Header newInstance() {
27 | return new Header();
28 | }
29 |
30 | public Header addParam(String key, String value) {
31 | if (!Strings.isNullOrEmpty(key)) {
32 | header.put(key, value);
33 | }
34 | return this;
35 | }
36 |
37 | public Header setContentType(String contentType) {
38 | if (contentType == null) {
39 | contentType = MediaType.FORM_DATA.toString();
40 | }
41 | return addParam(HttpHeaders.CONTENT_TYPE, contentType);
42 | }
43 |
44 | public Header build() {
45 | return this;
46 | }
47 |
48 | public String getValue(String key) {
49 | return header.get(key);
50 | }
51 |
52 | public Iterator> iterator() {
53 | return header.entrySet().iterator();
54 | }
55 |
56 | public String getCharset() {
57 | String acceptCharset = getValue(HttpHeaders.ACCEPT_CHARSET);
58 | if (acceptCharset == null) {
59 | String contentType = getValue(HttpHeaders.CONTENT_TYPE);
60 | acceptCharset =
61 | !Strings.isNullOrEmpty(contentType)
62 | ? analysisCharset(contentType)
63 | : StandardCharsets.UTF_8.displayName();
64 | }
65 | return acceptCharset;
66 | }
67 |
68 | private String analysisCharset(String contentType) {
69 | String[] values = contentType.split(";");
70 | String charset = StandardCharsets.UTF_8.displayName();
71 | if (values.length == 0) {
72 | return charset;
73 | }
74 | for (String value : values) {
75 | if (value.startsWith("charset=")) {
76 | charset = value.substring("charset=".length());
77 | }
78 | }
79 | return charset;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/common/PageInfo.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.common;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * dolphin scheduler page model,copied from org.apache.dolphinscheduler.api.utils.PageInfo
7 | *
8 | * @param
9 | */
10 | public class PageInfo {
11 |
12 | /** totalList */
13 | private List totalList;
14 | /** total */
15 | private Integer total = 0;
16 | /** total Page */
17 | private Integer totalPage;
18 | /** page size */
19 | private Integer pageSize = 20;
20 | /** current page */
21 | private Integer currentPage = 0;
22 | /** pageNo */
23 | private Integer pageNo;
24 |
25 | public PageInfo() {}
26 |
27 | public PageInfo(Integer currentPage, Integer pageSize) {
28 | if (currentPage == null) {
29 | currentPage = 1;
30 | }
31 | this.pageNo = (currentPage - 1) * pageSize;
32 | this.pageSize = pageSize;
33 | this.currentPage = currentPage;
34 | }
35 |
36 | public Integer getStart() {
37 | return pageNo;
38 | }
39 |
40 | public void setStart(Integer start) {
41 | this.pageNo = start;
42 | }
43 |
44 | public List getTotalList() {
45 | return totalList;
46 | }
47 |
48 | public void setTotalList(List totalList) {
49 | this.totalList = totalList;
50 | }
51 |
52 | public Integer getTotal() {
53 | if (total == null) {
54 | total = 0;
55 | }
56 | return total;
57 | }
58 |
59 | public void setTotal(Integer total) {
60 | this.total = total;
61 | }
62 |
63 | public Integer getTotalPage() {
64 | if (pageSize == null || pageSize == 0) {
65 | pageSize = 7;
66 | }
67 | this.totalPage =
68 | (this.total % this.pageSize) == 0
69 | ? ((this.total / this.pageSize) == 0 ? 1 : (this.total / this.pageSize))
70 | : (this.total / this.pageSize + 1);
71 | return this.totalPage;
72 | }
73 |
74 | public void setTotalPage(Integer totalPage) {
75 | this.totalPage = totalPage;
76 | }
77 |
78 | public Integer getPageSize() {
79 | if (pageSize == null || pageSize == 0) {
80 | pageSize = 7;
81 | }
82 | return pageSize;
83 | }
84 |
85 | public void setPageSize(Integer pageSize) {
86 | this.pageSize = pageSize;
87 | }
88 |
89 | public Integer getCurrentPage() {
90 | if (currentPage == null || currentPage <= 0) {
91 | this.currentPage = 1;
92 | }
93 | return currentPage;
94 | }
95 |
96 | public void setCurrentPage(Integer currentPage) {
97 | this.currentPage = currentPage;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/util/TaskUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.util;
2 |
3 | import com.fasterxml.jackson.databind.node.ArrayNode;
4 | import com.fasterxml.jackson.databind.node.ObjectNode;
5 | import com.github.weaksloth.dolphins.task.ConditionTask;
6 | import java.util.Collections;
7 | import java.util.List;
8 |
9 | /** utils for task node */
10 | public class TaskUtils {
11 |
12 | /**
13 | * build condition task
14 | *
15 | * @param successNodeCode the task to run when condition is success
16 | * @param failNodeCode the task to run when condition is fail
17 | * @param dependNodeCodeList dependency task, support multi dependency
18 | */
19 | public static ConditionTask buildConditionTask(
20 | Long successNodeCode, Long failNodeCode, List dependNodeCodeList) {
21 | ConditionTask conditionTask = new ConditionTask();
22 | ObjectNode dependence = JacksonUtils.createObjectNode();
23 | dependence.put("relation", "AND");
24 |
25 | ArrayNode dependTaskList = JacksonUtils.createArrayNode();
26 | ObjectNode dependTask = JacksonUtils.createObjectNode();
27 |
28 | ArrayNode dependItemList = JacksonUtils.createArrayNode();
29 |
30 | for (Long dependNodeCode : dependNodeCodeList) {
31 | ObjectNode dependItem = JacksonUtils.createObjectNode();
32 | dependItem.put("depTaskCode", dependNodeCode);
33 | dependItem.put("status", "SUCCESS");
34 | dependItemList.add(dependItem);
35 | }
36 |
37 | dependTask.put("relation", "AND");
38 | dependTask.set("dependItemList", dependItemList);
39 |
40 | dependTaskList.add(dependTask);
41 |
42 | dependence.set("dependTaskList", dependTaskList);
43 | conditionTask
44 | .setConditionResult(
45 | createConditionResult(
46 | Collections.singletonList(successNodeCode),
47 | Collections.singletonList(failNodeCode)))
48 | .setDependence(dependence);
49 | return conditionTask;
50 | }
51 |
52 | /** create empty condition result for most task */
53 | public static ObjectNode createEmptyConditionResult() {
54 | ObjectNode conditionResult = JacksonUtils.createObjectNode();
55 | conditionResult.put("successNode", JacksonUtils.createArrayNode());
56 | conditionResult.put("failedNode", JacksonUtils.createArrayNode());
57 | return conditionResult;
58 | }
59 |
60 | /**
61 | * create condition result with success node and fail node
62 | *
63 | * @param successNodeList the task when condition is success
64 | * @param failNodeList the task when condition is fail
65 | */
66 | public static ObjectNode createConditionResult(
67 | List successNodeList, List failNodeList) {
68 |
69 | ObjectNode conditionResult = JacksonUtils.createObjectNode();
70 | ArrayNode successNode = JacksonUtils.createArrayNode();
71 | ArrayNode failNode = JacksonUtils.createArrayNode();
72 |
73 | successNodeList.forEach(successNode::add);
74 | failNodeList.forEach(failNode::add);
75 |
76 | conditionResult.put("successNode", successNode);
77 | conditionResult.put("failedNode", failNode);
78 | return conditionResult;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.github.weaksloth
8 | dolphinscheduler-sdk-java
9 | 3.2.0-RELEASE
10 |
11 |
12 | 1.18.22
13 | 4.5.13
14 | 2.9.10
15 | 1.7.30
16 | 1.2.3
17 | 4.13
18 | 31.1-jre
19 |
20 |
21 |
22 |
23 |
24 | org.slf4j
25 | slf4j-api
26 | ${slf4j.version}
27 |
28 |
29 |
30 | ch.qos.logback
31 | logback-classic
32 | ${logback.version}
33 |
34 |
35 |
36 | org.projectlombok
37 | lombok
38 | ${lombok.version}
39 |
40 |
41 |
42 | org.apache.httpcomponents
43 | httpclient
44 | ${httpclient.version}
45 |
46 |
47 |
48 | org.apache.httpcomponents
49 | httpmime
50 | ${httpclient.version}
51 |
52 |
53 |
54 | com.fasterxml.jackson.core
55 | jackson-databind
56 | ${jackson.version}
57 |
58 |
59 |
60 | junit
61 | junit
62 | ${junit.version}
63 | test
64 |
65 |
66 |
67 | com.google.guava
68 | guava
69 | ${guava.version}
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | com.coveo
78 | fmt-maven-plugin
79 | 2.9.1
80 |
81 |
82 |
83 | format
84 |
85 |
86 |
87 |
88 |
89 | org.apache.maven.plugins
90 | maven-compiler-plugin
91 |
92 | 8
93 | 8
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/core/DolphinClient.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.core;
2 |
3 | import com.github.weaksloth.dolphins.datasource.DataSourceOperator;
4 | import com.github.weaksloth.dolphins.instance.ProcessInstanceOperator;
5 | import com.github.weaksloth.dolphins.process.ProcessOperator;
6 | import com.github.weaksloth.dolphins.project.ProjectOperator;
7 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
8 | import com.github.weaksloth.dolphins.resource.ResourceOperator;
9 | import com.github.weaksloth.dolphins.schedule.ScheduleOperator;
10 | import com.github.weaksloth.dolphins.taskinstance.TaskInstanceOperator;
11 | import com.github.weaksloth.dolphins.tenant.TenantOperator;
12 | import lombok.extern.slf4j.Slf4j;
13 |
14 | /** dolphin scheduler client to operate dolphin scheduler */
15 | @Slf4j
16 | public class DolphinClient {
17 |
18 | private final DolphinsRestTemplate dolphinsRestTemplate;
19 | private final String dolphinAddress;
20 | private final String token;
21 |
22 | private DataSourceOperator dataSourceOperator;
23 | private ResourceOperator resourceOperator;
24 | private ProcessOperator processOperator;
25 | private ProcessInstanceOperator processInstanceOperator;
26 | private ScheduleOperator scheduleOperator;
27 | private ProjectOperator projectOperator;
28 | private TenantOperator tenantOperator;
29 | private TaskInstanceOperator taskInstanceOperator;
30 |
31 | public DolphinClient(
32 | String token, String dolphinAddress, DolphinsRestTemplate dolphinsRestTemplate) {
33 | this.token = token;
34 | this.dolphinAddress = dolphinAddress;
35 | this.dolphinsRestTemplate = dolphinsRestTemplate;
36 | this.initOperators();
37 | }
38 |
39 | public void initOperators() {
40 | this.dataSourceOperator =
41 | new DataSourceOperator(this.dolphinAddress, this.token, this.dolphinsRestTemplate);
42 | this.resourceOperator =
43 | new ResourceOperator(this.dolphinAddress, this.token, this.dolphinsRestTemplate);
44 | this.processOperator =
45 | new ProcessOperator(this.dolphinAddress, this.token, this.dolphinsRestTemplate);
46 | this.processInstanceOperator =
47 | new ProcessInstanceOperator(this.dolphinAddress, this.token, this.dolphinsRestTemplate);
48 | this.scheduleOperator =
49 | new ScheduleOperator(this.dolphinAddress, this.token, this.dolphinsRestTemplate);
50 | this.projectOperator =
51 | new ProjectOperator(this.dolphinAddress, this.token, this.dolphinsRestTemplate);
52 | this.taskInstanceOperator =
53 | new TaskInstanceOperator(this.dolphinAddress, this.token, this.dolphinsRestTemplate);
54 | this.tenantOperator =
55 | new TenantOperator(this.dolphinAddress, this.token, this.dolphinsRestTemplate);
56 | }
57 |
58 | public DataSourceOperator opsForDataSource() {
59 | return this.dataSourceOperator;
60 | }
61 |
62 | public ResourceOperator opsForResource() {
63 | return this.resourceOperator;
64 | }
65 |
66 | public ProcessOperator opsForProcess() {
67 | return this.processOperator;
68 | }
69 |
70 | public ProcessInstanceOperator opsForProcessInst() {
71 | return this.processInstanceOperator;
72 | }
73 |
74 | public ScheduleOperator opsForSchedule() {
75 | return this.scheduleOperator;
76 | }
77 |
78 | public ProjectOperator opsForProject() {
79 | return this.projectOperator;
80 | }
81 |
82 | public TaskInstanceOperator opsForTaskInstance() {
83 | return this.taskInstanceOperator;
84 | }
85 |
86 | public TenantOperator opsForTenant() {
87 | return this.tenantOperator;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/enums/WorkflowExecutionStatus.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.enums;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import lombok.NonNull;
6 |
7 | public enum WorkflowExecutionStatus {
8 |
9 | // This class is split from ExecutionStatus #11339.
10 | // In order to compatible with the old value, the code is not consecutive
11 | SUBMITTED_SUCCESS(0, "submit success"),
12 | RUNNING_EXECUTION(1, "running"),
13 | READY_PAUSE(2, "ready pause"),
14 | PAUSE(3, "pause"),
15 | READY_STOP(4, "ready stop"),
16 | STOP(5, "stop"),
17 | FAILURE(6, "failure"),
18 | SUCCESS(7, "success"),
19 | DELAY_EXECUTION(12, "delay execution"),
20 | SERIAL_WAIT(14, "serial wait"),
21 | READY_BLOCK(15, "ready block"),
22 | BLOCK(16, "block"),
23 | WAIT_TO_RUN(17, "wait to run"),
24 | ;
25 |
26 | private static final Map CODE_MAP = new HashMap<>();
27 | private static final int[] NEED_FAILOVER_STATES =
28 | new int[] {
29 | SUBMITTED_SUCCESS.getCode(),
30 | RUNNING_EXECUTION.getCode(),
31 | DELAY_EXECUTION.getCode(),
32 | READY_PAUSE.getCode(),
33 | READY_STOP.getCode()
34 | };
35 |
36 | static {
37 | for (WorkflowExecutionStatus executionStatus : WorkflowExecutionStatus.values()) {
38 | CODE_MAP.put(executionStatus.getCode(), executionStatus);
39 | }
40 | }
41 |
42 | /**
43 | * Get WorkflowExecutionStatus by code, if the code is invalidated will throw {@link
44 | * IllegalArgumentException}.
45 | */
46 | public static @NonNull WorkflowExecutionStatus of(int code) {
47 | WorkflowExecutionStatus workflowExecutionStatus = CODE_MAP.get(code);
48 | if (workflowExecutionStatus == null) {
49 | throw new IllegalArgumentException(
50 | String.format("The workflow execution status code: %s is invalidated", code));
51 | }
52 | return workflowExecutionStatus;
53 | }
54 |
55 | public boolean isRunning() {
56 | return this == RUNNING_EXECUTION;
57 | }
58 |
59 | public boolean canStop() {
60 | return this == RUNNING_EXECUTION || this == READY_PAUSE;
61 | }
62 |
63 | public boolean isFinished() {
64 | // todo: do we need to remove pause/block in finished judge?
65 | return isSuccess() || isFailure() || isStop() || isPause() || isBlock();
66 | }
67 |
68 | /**
69 | * status is success
70 | *
71 | * @return status
72 | */
73 | public boolean isSuccess() {
74 | return this == SUCCESS;
75 | }
76 |
77 | public boolean isFailure() {
78 | return this == FAILURE;
79 | }
80 |
81 | public boolean isPause() {
82 | return this == PAUSE;
83 | }
84 |
85 | public boolean isReadyStop() {
86 | return this == READY_STOP;
87 | }
88 |
89 | public boolean isStop() {
90 | return this == STOP;
91 | }
92 |
93 | public boolean isBlock() {
94 | return this == BLOCK;
95 | }
96 |
97 | public static int[] getNeedFailoverWorkflowInstanceState() {
98 | return NEED_FAILOVER_STATES;
99 | }
100 |
101 | private final int code;
102 |
103 | private final String desc;
104 |
105 | WorkflowExecutionStatus(int code, String desc) {
106 | this.code = code;
107 | this.desc = desc;
108 | }
109 |
110 | public int getCode() {
111 | return code;
112 | }
113 |
114 | public String getDesc() {
115 | return desc;
116 | }
117 |
118 | @Override
119 | public String toString() {
120 | return "WorkflowExecutionStatus{" + "code=" + code + ", desc='" + desc + '\'' + '}';
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/taskinstance/TaskInstanceOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.taskinstance;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.github.weaksloth.dolphins.common.PageInfo;
6 | import com.github.weaksloth.dolphins.core.AbstractOperator;
7 | import com.github.weaksloth.dolphins.core.DolphinClientConstant;
8 | import com.github.weaksloth.dolphins.core.DolphinException;
9 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
10 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
11 | import com.github.weaksloth.dolphins.remote.Query;
12 | import com.github.weaksloth.dolphins.util.JacksonUtils;
13 | import java.util.List;
14 | import java.util.Optional;
15 | import lombok.extern.slf4j.Slf4j;
16 |
17 | @Slf4j
18 | public class TaskInstanceOperator extends AbstractOperator {
19 |
20 | public TaskInstanceOperator(
21 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
22 | super(dolphinAddress, token, dolphinsRestTemplate);
23 | }
24 |
25 | /**
26 | * page query task instance
27 | *
28 | * @param projectCode project code
29 | * @param page page
30 | * @param size size
31 | * @param processInstanceId process instance id
32 | * @return list
33 | */
34 | public List page(
35 | Long projectCode, Integer page, Integer size, Long processInstanceId) {
36 | page = Optional.ofNullable(page).orElse(DolphinClientConstant.Page.DEFAULT_PAGE);
37 | size = Optional.ofNullable(size).orElse(DolphinClientConstant.Page.DEFAULT_SIZE);
38 |
39 | String url = dolphinAddress + "/projects/" + projectCode + "/task-instances";
40 | Query query =
41 | new Query()
42 | .addParam("pageNo", String.valueOf(page))
43 | .addParam("pageSize", String.valueOf(size))
44 | .addParam("processInstanceId", String.valueOf(processInstanceId));
45 |
46 | try {
47 | HttpRestResult restResult =
48 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
49 |
50 | return JacksonUtils.parseObject(
51 | restResult.getData().toString(),
52 | new TypeReference>() {})
53 | .getTotalList();
54 | } catch (Exception e) {
55 | throw new DolphinException("list ds task instance fail", e);
56 | }
57 | }
58 |
59 | /**
60 | * query task instance log
61 | *
62 | * @param projectCode project code
63 | * @param skipLineNum skipLineNum
64 | * @param limit limit
65 | * @param taskInstanceId taskInstanceId
66 | * @return String
67 | */
68 | public String queryLog(
69 | Long projectCode, Integer skipLineNum, Integer limit, Long taskInstanceId) {
70 | skipLineNum =
71 | Optional.ofNullable(skipLineNum).orElse(DolphinClientConstant.LogLimit.DEFAULT_SKIP);
72 | limit = Optional.ofNullable(limit).orElse(DolphinClientConstant.LogLimit.DEFAULT_LIMIT);
73 |
74 | String url = dolphinAddress + "/log/" + projectCode + "/detail";
75 | Query query =
76 | new Query()
77 | .addParam("projectCode", String.valueOf(projectCode))
78 | .addParam("taskInstanceId", String.valueOf(taskInstanceId))
79 | .addParam("skipLineNum", String.valueOf(skipLineNum))
80 | .addParam("limit", String.valueOf(limit));
81 |
82 | try {
83 | HttpRestResult restResult =
84 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
85 |
86 | return restResult.getData().toString();
87 | } catch (Exception e) {
88 | throw new DolphinException("query ds log detail fail", e);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/instance/ProcessInstanceQueryResp.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.instance;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5 | import com.github.weaksloth.dolphins.process.ProcessDefineResp;
6 | import java.util.Date;
7 | import lombok.Data;
8 | import lombok.experimental.Accessors;
9 |
10 | /** copied from org.apache.dolphinscheduler.dao.entity.ProcessInstance */
11 | @Data
12 | @Accessors(chain = true)
13 | @JsonIgnoreProperties(ignoreUnknown = true)
14 | public class ProcessInstanceQueryResp {
15 |
16 | /** id */
17 | private int id;
18 |
19 | /** process definition code */
20 | private Long processDefinitionCode;
21 |
22 | /** process definition version */
23 | private int processDefinitionVersion;
24 |
25 | /** process state */
26 | private String state;
27 | /** recovery flag for failover */
28 | private String recovery;
29 | /** start time */
30 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
31 | private Date startTime;
32 |
33 | /** end time */
34 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
35 | private Date endTime;
36 |
37 | /** run time */
38 | private int runTimes;
39 |
40 | /** name */
41 | private String name;
42 |
43 | /** host */
44 | private String host;
45 |
46 | /** process definition structure */
47 | private ProcessDefineResp processDefinition;
48 | /** process command type */
49 | private String commandType;
50 |
51 | /** command parameters */
52 | private String commandParam;
53 |
54 | /** node depend type */
55 | private String taskDependType;
56 |
57 | /** task max try times */
58 | private int maxTryTimes;
59 |
60 | /** failure strategy when task failed.continue or end */
61 | private String failureStrategy;
62 |
63 | /** warning type */
64 | private String warningType;
65 |
66 | /** warning group */
67 | private Integer warningGroupId;
68 |
69 | /** schedule time */
70 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
71 | private Date scheduleTime;
72 |
73 | /** command start time */
74 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
75 | private Date commandStartTime;
76 |
77 | /** user define parameters string */
78 | private String globalParams;
79 |
80 | /** executor id */
81 | private int executorId;
82 |
83 | /** executor name */
84 | private String executorName;
85 |
86 | /** tenant code */
87 | private String tenantCode;
88 |
89 | /** queue */
90 | private String queue;
91 |
92 | /** process is sub process */
93 | private String isSubProcess;
94 |
95 | /** task locations for web */
96 | private String locations;
97 |
98 | /** history command */
99 | private String historyCmd;
100 |
101 | /** depend processes schedule time */
102 | private String dependenceScheduleTimes;
103 |
104 | /**
105 | * process duration
106 | *
107 | * @return
108 | */
109 | private String duration;
110 |
111 | /** process instance priority */
112 | private String processInstancePriority;
113 |
114 | /** worker group */
115 | private String workerGroup;
116 |
117 | /** environment code */
118 | private Long environmentCode;
119 |
120 | /** process timeout for warning */
121 | private int timeout;
122 |
123 | /** tenant id */
124 | private int tenantId;
125 |
126 | /** varPool string */
127 | private String varPool;
128 |
129 | /** dry run flag */
130 | private int dryRun;
131 |
132 | /** re-start time */
133 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
134 | private Date restartTime;
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/datasource/DataSourceOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.datasource;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.github.weaksloth.dolphins.common.PageInfo;
6 | import com.github.weaksloth.dolphins.core.AbstractOperator;
7 | import com.github.weaksloth.dolphins.core.DolphinException;
8 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
9 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
10 | import com.github.weaksloth.dolphins.remote.Query;
11 | import com.github.weaksloth.dolphins.util.JacksonUtils;
12 | import java.util.List;
13 | import lombok.extern.slf4j.Slf4j;
14 |
15 | /** operator for operate datasource */
16 | @Slf4j
17 | public class DataSourceOperator extends AbstractOperator {
18 |
19 | public DataSourceOperator(
20 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
21 | super(dolphinAddress, token, dolphinsRestTemplate);
22 | }
23 |
24 | /**
25 | * create datasource, api:/dolphinscheduler/datasources
26 | *
27 | * @param dataSourceCreateParam create datasource param
28 | * @return true for success,otherwise false
29 | */
30 | public Boolean create(DataSourceCreateParam dataSourceCreateParam) {
31 | String url = dolphinAddress + "/datasources";
32 | try {
33 | HttpRestResult result =
34 | dolphinsRestTemplate.postJson(url, getHeader(), dataSourceCreateParam, String.class);
35 | log.info("create datasource response:{}", result);
36 | return result.getSuccess();
37 | } catch (Exception e) {
38 | throw new DolphinException("create dolphin scheduler datasource fail", e);
39 | }
40 | }
41 |
42 | /**
43 | * update datasource, api:/dolphinscheduler/datasources/{id}
44 | *
45 | * @param dataSourceUpdateParam update datasource param
46 | * @return true for success,otherwise false
47 | */
48 | public Boolean update(DataSourceUpdateParam dataSourceUpdateParam) {
49 | String url = dolphinAddress + "/datasources/" + dataSourceUpdateParam.getId();
50 | try {
51 | HttpRestResult result =
52 | dolphinsRestTemplate.putJson(url, getHeader(), dataSourceUpdateParam, String.class);
53 | log.info("update datasource response:{}", result);
54 | return result.getSuccess();
55 | } catch (Exception e) {
56 | throw new DolphinException("update dolphin scheduler datasource fail", e);
57 | }
58 | }
59 |
60 | /**
61 | * delete dolphin scheduler datasource
62 | *
63 | * @param id dolphin scheduler datasource id
64 | * @return true for success,otherwise false
65 | */
66 | public Boolean delete(Long id) {
67 | String url = dolphinAddress + "/datasources/" + id;
68 | try {
69 | HttpRestResult result =
70 | dolphinsRestTemplate.delete(url, getHeader(), null, String.class);
71 | log.info("delete datasource response:{}", result);
72 | return result.getSuccess();
73 | } catch (Exception e) {
74 | throw new DolphinException("delete dolphin scheduler datasource fail", e);
75 | }
76 | }
77 |
78 | /**
79 | * page query dolphin datasource list ,api:/dolphinscheduler/datasources
80 | *
81 | * @return {@link List }
82 | */
83 | public List list(String dsName) {
84 | String url = dolphinAddress + "/datasources";
85 | Query query =
86 | new Query()
87 | .addParam("pageNo", "1")
88 | .addParam("pageSize", "10")
89 | .addParam("searchVal", dsName)
90 | .build();
91 | try {
92 | HttpRestResult stringHttpRestResult =
93 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
94 | return JacksonUtils.parseObject(
95 | stringHttpRestResult.getData().toString(),
96 | new TypeReference>() {})
97 | .getTotalList();
98 | } catch (Exception e) {
99 | throw new DolphinException("list dolphin scheduler datasource fail", e);
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/test/java/com/github/weaksloth/dolphins/workflow/WorkflowTest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.workflow;
2 |
3 | import com.github.weaksloth.dolphins.BaseTest;
4 | import com.github.weaksloth.dolphins.enums.HttpCheckCondition;
5 | import com.github.weaksloth.dolphins.enums.HttpMethod;
6 | import com.github.weaksloth.dolphins.process.*;
7 | import com.github.weaksloth.dolphins.task.HttpTask;
8 | import com.github.weaksloth.dolphins.task.ShellTask;
9 | import com.github.weaksloth.dolphins.util.TaskDefinitionUtils;
10 | import com.github.weaksloth.dolphins.util.TaskLocationUtils;
11 | import com.github.weaksloth.dolphins.util.TaskRelationUtils;
12 | import com.github.weaksloth.dolphins.util.TaskUtils;
13 | import java.util.Arrays;
14 | import java.util.List;
15 | import org.junit.Assert;
16 | import org.junit.Test;
17 |
18 | /** the test for workflow/process */
19 | public class WorkflowTest extends BaseTest {
20 |
21 | public static final String WORKFLOW_NAME = "test-dag2";
22 |
23 | /**
24 | * create simple workflow like: shellTask -> httpTask
25 | *
26 | * 1.generate task code
27 | *
28 | *
2.create tasks
29 | *
30 | *
3.create task definitions
31 | *
32 | *
4.create task relations
33 | *
34 | *
5.create process create parm
35 | *
36 | *
37 | */
38 | @Test
39 | public void testCreateProcessDefinition() {
40 |
41 | List taskCodes = getClient().opsForProcess().generateTaskCode(projectCode, 2);
42 |
43 | // build shell task
44 | ShellTask shellTask = new ShellTask();
45 | shellTask.setRawScript("echo 'hello dolphin scheduler java sdk'");
46 | TaskDefinition shellTaskDefinition =
47 | TaskDefinitionUtils.createDefaultTaskDefinition(taskCodes.get(0), shellTask);
48 |
49 | // build http task
50 | HttpTask httpTask = new HttpTask();
51 | httpTask
52 | .setUrl("http://www.baidu.com")
53 | .setHttpMethod(HttpMethod.GET.toString())
54 | .setHttpCheckCondition(HttpCheckCondition.STATUS_CODE_DEFAULT.toString())
55 | .setCondition("")
56 | .setConditionResult(TaskUtils.createEmptyConditionResult());
57 | TaskDefinition httpTaskDefinition =
58 | TaskDefinitionUtils.createDefaultTaskDefinition(taskCodes.get(1), httpTask);
59 |
60 | ProcessDefineParam pcr = new ProcessDefineParam();
61 | pcr.setName(WORKFLOW_NAME)
62 | .setLocations(TaskLocationUtils.horizontalLocation(taskCodes.toArray(new Long[0])))
63 | .setDescription("test-dag-description")
64 | .setTenantCode(tenantCode)
65 | .setTimeout("0")
66 | .setExecutionType(ProcessDefineParam.EXECUTION_TYPE_PARALLEL)
67 | .setTaskDefinitionJson(Arrays.asList(shellTaskDefinition, httpTaskDefinition))
68 | .setTaskRelationJson(TaskRelationUtils.oneLineRelation(taskCodes.toArray(new Long[0])))
69 | .setGlobalParams(null);
70 |
71 | System.out.println(getClient().opsForProcess().create(projectCode, pcr));
72 | }
73 |
74 | @Test
75 | public void testPage() {
76 | List page =
77 | getClient().opsForProcess().page(projectCode, null, null, WORKFLOW_NAME);
78 | int expectedWorkflowNumber = 1;
79 | Assert.assertEquals(expectedWorkflowNumber, page.size());
80 | }
81 |
82 | @Test
83 | public void testOnlineWorkflow() {
84 | List page =
85 | getClient().opsForProcess().page(projectCode, null, null, WORKFLOW_NAME);
86 | Assert.assertTrue(getClient().opsForProcess().online(projectCode, page.get(0).getCode()));
87 | }
88 |
89 | @Test
90 | public void testOfflineWorkflow() {
91 | List page =
92 | getClient().opsForProcess().page(projectCode, null, null, WORKFLOW_NAME);
93 | Assert.assertTrue(getClient().opsForProcess().offline(projectCode, page.get(0).getCode()));
94 | }
95 |
96 | /** the workflow must in offline state */
97 | @Test
98 | public void testDeleteWorkflow() {
99 | List page =
100 | getClient().opsForProcess().page(projectCode, null, null, WORKFLOW_NAME);
101 | Assert.assertTrue(getClient().opsForProcess().delete(projectCode, page.get(0).getCode()));
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/tenant/TenantOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.tenant;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.github.weaksloth.dolphins.common.PageInfo;
6 | import com.github.weaksloth.dolphins.core.AbstractOperator;
7 | import com.github.weaksloth.dolphins.core.DolphinClientConstant;
8 | import com.github.weaksloth.dolphins.core.DolphinException;
9 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
10 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
11 | import com.github.weaksloth.dolphins.remote.Query;
12 | import com.github.weaksloth.dolphins.util.JacksonUtils;
13 | import java.util.List;
14 | import java.util.Optional;
15 | import lombok.extern.slf4j.Slf4j;
16 |
17 | /** operator for tenant */
18 | @Slf4j
19 | public class TenantOperator extends AbstractOperator {
20 |
21 | public TenantOperator(
22 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
23 | super(dolphinAddress, token, dolphinsRestTemplate);
24 | }
25 |
26 | /**
27 | * create tenant, api: /dolphinscheduler/tenants
28 | *
29 | * @param tenantDefineParam create tenant param
30 | * @return tenant info
31 | */
32 | public TenantInfoResp create(TenantDefineParam tenantDefineParam) {
33 | String url = dolphinAddress + "/tenants";
34 | try {
35 | HttpRestResult result =
36 | dolphinsRestTemplate.postForm(url, getHeader(), tenantDefineParam, TenantInfoResp.class);
37 | if (result.getSuccess()) {
38 | return result.getData();
39 | } else {
40 | log.error("create tenant response:{}", result);
41 | throw new DolphinException("create dolphin scheduler tenant fail");
42 | }
43 | } catch (Exception e) {
44 | throw new DolphinException("create dolphin scheduler tenant fail", e);
45 | }
46 | }
47 |
48 | /**
49 | * create tenant, api: /dolphinscheduler/tenants/{id}
50 | *
51 | * @param updateParam update tenant param
52 | * @return tenant info
53 | */
54 | public Boolean update(Long tenantId, TenantDefineParam updateParam) {
55 | String url = dolphinAddress + "/tenants/" + tenantId;
56 | try {
57 | HttpRestResult result =
58 | dolphinsRestTemplate.putForm(url, getHeader(), updateParam, String.class);
59 | log.info("update tenant response:{}", result);
60 | return result.getSuccess();
61 | } catch (Exception e) {
62 | throw new DolphinException("update dolphin scheduler tenant fail", e);
63 | }
64 | }
65 |
66 | /**
67 | * delete dolphin scheduler tenant
68 | *
69 | * @param tenantId dolphin scheduler tenant id
70 | * @return true for success,otherwise false
71 | */
72 | public Boolean delete(Long tenantId) {
73 | String url = dolphinAddress + "/tenants/" + tenantId;
74 | try {
75 | HttpRestResult result =
76 | dolphinsRestTemplate.delete(url, getHeader(), null, String.class);
77 | log.info("delete tenant response:{}", result);
78 | return result.getSuccess();
79 | } catch (Exception e) {
80 | throw new DolphinException("delete dolphin scheduler tenant fail", e);
81 | }
82 | }
83 |
84 | /**
85 | * page query tenant list ,api:/dolphinscheduler/tenants
86 | *
87 | * @param page page number
88 | * @param size page size
89 | * @param tenantCode tenant code, such as root.
90 | * @return {@link List}
91 | */
92 | public List page(Integer page, Integer size, String tenantCode) {
93 |
94 | page = Optional.ofNullable(page).orElse(DolphinClientConstant.Page.DEFAULT_PAGE);
95 | size = Optional.ofNullable(size).orElse(DolphinClientConstant.Page.DEFAULT_SIZE);
96 |
97 | String url = dolphinAddress + "/tenants";
98 | Query query =
99 | new Query()
100 | .addParam("pageNo", String.valueOf(page))
101 | .addParam("pageSize", String.valueOf(size))
102 | .addParam("searchVal", tenantCode)
103 | .build();
104 | try {
105 | HttpRestResult stringHttpRestResult =
106 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
107 | return JacksonUtils.parseObject(
108 | stringHttpRestResult.getData().toString(),
109 | new TypeReference>() {})
110 | .getTotalList();
111 | } catch (Exception e) {
112 | throw new DolphinException("list dolphin scheduler tenant fail", e);
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/project/ProjectOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.project;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.github.weaksloth.dolphins.common.PageInfo;
6 | import com.github.weaksloth.dolphins.core.AbstractOperator;
7 | import com.github.weaksloth.dolphins.core.DolphinClientConstant;
8 | import com.github.weaksloth.dolphins.core.DolphinException;
9 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
10 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
11 | import com.github.weaksloth.dolphins.remote.Query;
12 | import com.github.weaksloth.dolphins.util.JacksonUtils;
13 | import java.util.List;
14 | import java.util.Optional;
15 | import lombok.extern.slf4j.Slf4j;
16 |
17 | /** operator for operate project */
18 | @Slf4j
19 | public class ProjectOperator extends AbstractOperator {
20 |
21 | public ProjectOperator(
22 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
23 | super(dolphinAddress, token, dolphinsRestTemplate);
24 | }
25 |
26 | /**
27 | * create project, api:/dolphinscheduler/projects
28 | *
29 | * @param projectCreateParam create project param
30 | * @return project info
31 | */
32 | public ProjectInfoResp create(ProjectCreateParam projectCreateParam) {
33 | String url = dolphinAddress + "/projects";
34 | try {
35 | HttpRestResult result =
36 | dolphinsRestTemplate.postForm(
37 | url, getHeader(), projectCreateParam, ProjectInfoResp.class);
38 | if (result.getSuccess()) {
39 | return result.getData();
40 | } else {
41 | log.error("create project response:{}", result);
42 | throw new DolphinException("create dolphin scheduler project fail");
43 | }
44 | } catch (Exception e) {
45 | throw new DolphinException("create dolphin scheduler project fail", e);
46 | }
47 | }
48 |
49 | /**
50 | * update project, api:/dolphinscheduler/projects/{code}
51 | *
52 | * @param projectUpdateParam update project param
53 | * @return true for success,otherwise false
54 | */
55 | public ProjectInfoResp update(ProjectUpdateParam projectUpdateParam) {
56 | String url = dolphinAddress + "/projects/" + projectUpdateParam.getProjectCode();
57 | try {
58 | HttpRestResult result =
59 | dolphinsRestTemplate.putForm(url, getHeader(), projectUpdateParam, ProjectInfoResp.class);
60 | if (result.getSuccess()) {
61 | return result.getData();
62 | } else {
63 | log.error("update project response:{}", result);
64 | throw new DolphinException("update dolphin scheduler project fail");
65 | }
66 | } catch (Exception e) {
67 | throw new DolphinException("update dolphin scheduler project fail", e);
68 | }
69 | }
70 |
71 | /**
72 | * delete dolphin scheduler project
73 | *
74 | * @param projectCode dolphin scheduler project code
75 | * @return true for success,otherwise false
76 | */
77 | public Boolean delete(Long projectCode) {
78 | String url = dolphinAddress + "/projects/" + projectCode;
79 | try {
80 | HttpRestResult result =
81 | dolphinsRestTemplate.delete(url, getHeader(), null, String.class);
82 | log.info("delete project response:{}", result);
83 | return result.getSuccess();
84 | } catch (Exception e) {
85 | throw new DolphinException("delete dolphin scheduler project fail", e);
86 | }
87 | }
88 |
89 | /**
90 | * page query project list ,api:/dolphinscheduler/projects
91 | *
92 | * @param page page number
93 | * @param size page size
94 | * @param projectName project's name query criteria
95 | * @return {@link List}
96 | */
97 | public List page(Integer page, Integer size, String projectName) {
98 |
99 | page = Optional.ofNullable(page).orElse(DolphinClientConstant.Page.DEFAULT_PAGE);
100 | size = Optional.ofNullable(size).orElse(DolphinClientConstant.Page.DEFAULT_SIZE);
101 |
102 | String url = dolphinAddress + "/projects";
103 | Query query =
104 | new Query()
105 | .addParam("pageNo", String.valueOf(page))
106 | .addParam("pageSize", String.valueOf(size))
107 | .addParam("searchVal", projectName)
108 | .build();
109 | try {
110 | HttpRestResult stringHttpRestResult =
111 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
112 | return JacksonUtils.parseObject(
113 | stringHttpRestResult.getData().toString(),
114 | new TypeReference>() {})
115 | .getTotalList();
116 | } catch (Exception e) {
117 | throw new DolphinException("list dolphin scheduler project fail", e);
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/util/TaskDefinitionUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.util;
2 |
3 | import com.github.weaksloth.dolphins.process.TaskDefinition;
4 | import com.github.weaksloth.dolphins.task.AbstractTask;
5 | import com.google.common.base.Strings;
6 | import java.util.Optional;
7 |
8 | public class TaskDefinitionUtils {
9 |
10 | public static final String FLAG_YES = "YES"; // the node will be executed
11 | public static final String FLAG_NO = "NO"; // the node will not be executed
12 |
13 | public static final String PRIORITY_HIGHEST = "HIGHEST";
14 | public static final String PRIORITY_HIGH = "HIGH";
15 | public static final String PRIORITY_MEDIUM = "MEDIUM";
16 | public static final String PRIORITY_LOW = "LOW";
17 | public static final String PRIORITY_LOWEST = "LOWEST";
18 |
19 | public static final String IS_CACHE_YES = "YES"; // execution cache
20 | public static final String IS_CACHE_NO = "NO"; // execution not cache
21 |
22 | /**
23 | * create task definition with default config {@link TaskDefinition} which can satisfy basic needs
24 | *
25 | * @param taskCode task node's code,generate by api
26 | * @param task {@link AbstractTask}
27 | */
28 | public static TaskDefinition createDefaultTaskDefinition(Long taskCode, AbstractTask task) {
29 | return createTaskDefinition(null, taskCode, 0, task, FLAG_YES, PRIORITY_MEDIUM, null, null);
30 | }
31 |
32 | /**
33 | * create task definition with default config {@link TaskDefinition} which can satisfy basic needs
34 | *
35 | * @param taskName task node's name
36 | * @param taskCode task node's code,generate by api
37 | * @param task {@link AbstractTask}
38 | */
39 | public static TaskDefinition createDefaultTaskDefinition(
40 | String taskName, Long taskCode, AbstractTask task) {
41 | return createTaskDefinition(taskName, taskCode, 0, task, FLAG_YES, PRIORITY_MEDIUM, null, null);
42 | }
43 |
44 | /**
45 | * create task definition with default config {@link TaskDefinition} which can satisfy basic needs
46 | *
47 | * @param taskCode task node's code,generate by api
48 | * @param version task node's version
49 | * @param task {@link AbstractTask}
50 | */
51 | public static TaskDefinition createDefaultTaskDefinition(
52 | Long taskCode, Integer version, AbstractTask task) {
53 | return createTaskDefinition(
54 | null, taskCode, version, task, FLAG_YES, PRIORITY_MEDIUM, null, null);
55 | }
56 |
57 | /**
58 | * create task which wll not be executed
59 | *
60 | * @param taskCode task node's code,generate by api
61 | * @param task {@link AbstractTask}
62 | */
63 | public static TaskDefinition createBannedTaskDefinition(
64 | Long taskCode, Integer version, AbstractTask task) {
65 | return createTaskDefinition(
66 | null, taskCode, version, task, FLAG_NO, PRIORITY_MEDIUM, null, null);
67 | }
68 |
69 | /**
70 | * create high priority task
71 | *
72 | * @param taskCode task node's code,generate by api
73 | * @param task {@link AbstractTask}
74 | */
75 | public static TaskDefinition createHighLevelTaskDefinition(
76 | Long taskCode, Integer version, AbstractTask task) {
77 | return createTaskDefinition(null, taskCode, version, task, FLAG_YES, PRIORITY_HIGH, null, null);
78 | }
79 |
80 | /**
81 | * create task definition
82 | *
83 | * @param taskName task node's name
84 | * @param taskCode task node's code,generate by api
85 | * @param version task node's version
86 | * @param task {@link AbstractTask}
87 | * @param flag YES or NO
88 | * @param cpuQuota cpu resource
89 | * @param memoryMax memory resource
90 | * @param taskPriority {@link #PRIORITY_HIGH,#PRIORITY_HIGHEST}...
91 | */
92 | public static TaskDefinition createTaskDefinition(
93 | String taskName,
94 | Long taskCode,
95 | Integer version,
96 | AbstractTask task,
97 | String flag,
98 | String taskPriority,
99 | Integer cpuQuota,
100 | Long memoryMax) {
101 | TaskDefinition taskDefinition = new TaskDefinition();
102 | if (Strings.isNullOrEmpty(taskName)) {
103 | taskName = task.getTaskType().concat(String.valueOf(System.currentTimeMillis()));
104 | }
105 |
106 | taskDefinition
107 | .setCode(taskCode)
108 | .setVersion(version)
109 | .setName(taskName)
110 | .setDescription("")
111 | .setTaskType(task.getTaskType())
112 | .setTaskParams(task)
113 | .setFlag(flag)
114 | .setTaskPriority(taskPriority)
115 | .setWorkerGroup("default")
116 | .setFailRetryTimes("0")
117 | .setFailRetryInterval("1")
118 | .setTimeoutFlag("CLOSE")
119 | .setTimeoutNotifyStrategy("WARN")
120 | .setIsCache("NO");
121 | Optional.ofNullable(cpuQuota).ifPresent(taskDefinition::setCpuQuota);
122 | Optional.ofNullable(memoryMax).ifPresent(taskDefinition::setMemoryMax);
123 | return taskDefinition;
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/resource/ResourceOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.resource;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.github.weaksloth.dolphins.common.PageInfo;
6 | import com.github.weaksloth.dolphins.core.AbstractOperator;
7 | import com.github.weaksloth.dolphins.core.DolphinClientConstant;
8 | import com.github.weaksloth.dolphins.core.DolphinException;
9 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
10 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
11 | import com.github.weaksloth.dolphins.remote.Query;
12 | import com.github.weaksloth.dolphins.util.JacksonUtils;
13 | import java.util.List;
14 | import java.util.Optional;
15 | import lombok.extern.slf4j.Slf4j;
16 |
17 | // TODO support upload file
18 | @Slf4j
19 | public class ResourceOperator extends AbstractOperator {
20 |
21 | public ResourceOperator(
22 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
23 | super(dolphinAddress, token, dolphinsRestTemplate);
24 | }
25 |
26 | /**
27 | * page query resource list
28 | *
29 | * @param pid pid
30 | * @param fileName file name
31 | * @return {@link List }
32 | */
33 | public List page(Integer page, Integer size, String pid, String fileName) {
34 |
35 | page = Optional.ofNullable(page).orElse(DolphinClientConstant.Page.DEFAULT_PAGE);
36 | size = Optional.ofNullable(size).orElse(DolphinClientConstant.Page.DEFAULT_SIZE);
37 |
38 | String url = dolphinAddress + "/resources";
39 | Query query =
40 | new Query()
41 | .addParam("type", DolphinClientConstant.Resource.TYPE_FILE)
42 | .addParam("pageNo", String.valueOf(page))
43 | .addParam("pageSize", String.valueOf(size))
44 | .addParam("searchVal", fileName)
45 | .addParam("fullName", "")
46 | .addParam("tenantCode", "")
47 | .addParam("id", pid);
48 | try {
49 | HttpRestResult restResult =
50 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
51 |
52 | return JacksonUtils.parseObject(
53 | restResult.getData().toString(), new TypeReference>() {})
54 | .getTotalList();
55 | } catch (Exception e) {
56 | throw new DolphinException("list dolphin scheduler resource fail", e);
57 | }
58 | }
59 |
60 | /**
61 | * upload resource
62 | *
63 | * @param resourceUploadParam upload file param
64 | * @return resource info
65 | */
66 | public Boolean upload(ResourceUploadParam resourceUploadParam) {
67 | String url = dolphinAddress + "/resources";
68 |
69 | try {
70 | HttpRestResult restResult =
71 | dolphinsRestTemplate.postFileForm(url, getHeader(), resourceUploadParam, String.class);
72 | return restResult.getSuccess();
73 | } catch (Exception e) {
74 | throw new DolphinException("upload dolphin scheduler resource fail.", e);
75 | }
76 | }
77 |
78 | /**
79 | * online create resource/file
80 | *
81 | * @param resourceCreateParam online create file param
82 | * @return true for success,otherwise false
83 | */
84 | public Boolean onlineCreate(ResourceCreateParam resourceCreateParam) {
85 | String url = dolphinAddress + "/resources/online-create";
86 | try {
87 | HttpRestResult restResult =
88 | dolphinsRestTemplate.postForm(url, getHeader(), resourceCreateParam, String.class);
89 | return restResult.getSuccess();
90 | } catch (Exception e) {
91 | throw new DolphinException("online create resource fail", e);
92 | }
93 | }
94 |
95 | /**
96 | * online update resource/file
97 | *
98 | * @param resourceUpdateParam online update resource param
99 | * @return true for success,otherwise false
100 | */
101 | public Boolean onlineUpdate(ResourceUpdateParam resourceUpdateParam) {
102 | String url = dolphinAddress + "/resources/update-content";
103 | try {
104 | HttpRestResult restResult =
105 | dolphinsRestTemplate.putForm(url, getHeader(), resourceUpdateParam, String.class);
106 | return restResult.getSuccess();
107 | } catch (Exception e) {
108 | throw new DolphinException("online update resource fail", e);
109 | }
110 | }
111 |
112 | /**
113 | * delete resource by id
114 | *
115 | * @param tenantCode tenantCode
116 | * @param fullName fullName
117 | * @return
118 | */
119 | public Boolean delete(String tenantCode, String fullName) {
120 | String url = dolphinAddress + "/resources";
121 | Query query = new Query().addParam("tenantCode", tenantCode).addParam("fullName", fullName);
122 | try {
123 | HttpRestResult restResult =
124 | dolphinsRestTemplate.delete(url, getHeader(), query, String.class);
125 | return restResult.getSuccess();
126 | } catch (Exception e) {
127 | throw new DolphinException("delete resource fail", e);
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/taskinstance/TaskInstanceQueryResp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to the Apache Software Foundation (ASF) under one or more
3 | * contributor license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright ownership.
5 | * The ASF licenses this file to You under the Apache License, Version 2.0
6 | * (the "License"); you may not use this file except in compliance with
7 | * the License. You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package com.github.weaksloth.dolphins.taskinstance;
19 |
20 | import com.fasterxml.jackson.annotation.JsonFormat;
21 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
22 | import com.github.weaksloth.dolphins.instance.ProcessInstanceQueryResp;
23 | import com.github.weaksloth.dolphins.process.ProcessDefineResp;
24 | import com.github.weaksloth.dolphins.process.TaskDefinition;
25 | import java.io.Serializable;
26 | import java.util.Date;
27 | import java.util.Map;
28 | import lombok.Data;
29 | import lombok.experimental.Accessors;
30 |
31 | /** copied from org.apache.dolphinscheduler.dao.entity.TaskInstance */
32 | @Data
33 | @Accessors(chain = true)
34 | @JsonIgnoreProperties(ignoreUnknown = true)
35 | public class TaskInstanceQueryResp implements Serializable {
36 |
37 | /** id */
38 | private Integer id;
39 |
40 | /** task name */
41 | private String name;
42 |
43 | /** task type */
44 | private String taskType;
45 |
46 | private int processInstanceId;
47 |
48 | private String processInstanceName;
49 |
50 | private Long projectCode;
51 |
52 | private long taskCode;
53 |
54 | private int taskDefinitionVersion;
55 |
56 | private String processDefinitionName;
57 |
58 | /** process instance name */
59 | private int taskGroupPriority;
60 |
61 | /** state */
62 | private String state;
63 |
64 | /** task first submit time. */
65 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
66 | private Date firstSubmitTime;
67 |
68 | /** task submit time */
69 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
70 | private Date submitTime;
71 |
72 | /** task start time */
73 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
74 | private Date startTime;
75 |
76 | /** task end time */
77 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
78 | private Date endTime;
79 |
80 | /** task host */
81 | private String host;
82 |
83 | /**
84 | * task shell execute path and the resource down from hdfs default path:
85 | * $base_run_dir/processInstanceId/taskInstanceId/retryTimes
86 | */
87 | private String executePath;
88 |
89 | /** task log path default path: $base_run_dir/processInstanceId/taskInstanceId/retryTimes */
90 | private String logPath;
91 |
92 | /** retry times */
93 | private int retryTimes;
94 |
95 | /** alert flag */
96 | private String alertFlag;
97 |
98 | /** process instance */
99 | private ProcessInstanceQueryResp processInstance;
100 |
101 | /** process definition */
102 | private ProcessDefineResp processDefine;
103 |
104 | /** task definition */
105 | private TaskDefinition taskDefine;
106 |
107 | /** process id */
108 | private int pid;
109 |
110 | /** appLink */
111 | private String appLink;
112 |
113 | /** flag */
114 | private String flag;
115 |
116 | /** task is cache: yes/no */
117 | private String isCache;
118 |
119 | /** cache_key */
120 | private String cacheKey;
121 |
122 | /** dependency */
123 | private String dependency;
124 |
125 | /** switch dependency */
126 | private String switchDependency;
127 |
128 | /** duration */
129 | private String duration;
130 |
131 | /** max retry times */
132 | private int maxRetryTimes;
133 |
134 | /** task retry interval, unit: minute */
135 | private int retryInterval;
136 |
137 | /** task intance priority */
138 | private String taskInstancePriority;
139 |
140 | /** process intance priority */
141 | private String processInstancePriority;
142 |
143 | /** dependent state */
144 | private String dependentResult;
145 |
146 | /** workerGroup */
147 | private String workerGroup;
148 |
149 | /** environment code */
150 | private Long environmentCode;
151 |
152 | /** environment config */
153 | private String environmentConfig;
154 |
155 | /** executor id */
156 | private int executorId;
157 |
158 | /** varPool string */
159 | private String varPool;
160 |
161 | private String executorName;
162 |
163 | private Map resources;
164 |
165 | /** delay execution time. */
166 | private int delayTime;
167 |
168 | /** task params */
169 | private String taskParams;
170 |
171 | /** dry run flag */
172 | private int dryRun;
173 | /** task group id */
174 | private int taskGroupId;
175 |
176 | /** cpu quota */
177 | private Integer cpuQuota;
178 |
179 | /** max memory */
180 | private Integer memoryMax;
181 |
182 | /** task execute type */
183 | private String taskExecuteType;
184 |
185 | /** test flag */
186 | private int testFlag;
187 | }
188 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/schedule/ScheduleOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.schedule;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.github.weaksloth.dolphins.common.PageInfo;
6 | import com.github.weaksloth.dolphins.core.AbstractOperator;
7 | import com.github.weaksloth.dolphins.core.DolphinException;
8 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
9 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
10 | import com.github.weaksloth.dolphins.remote.Query;
11 | import com.github.weaksloth.dolphins.util.JacksonUtils;
12 | import java.util.List;
13 | import lombok.extern.slf4j.Slf4j;
14 |
15 | @Slf4j
16 | public class ScheduleOperator extends AbstractOperator {
17 |
18 | public ScheduleOperator(
19 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
20 | super(dolphinAddress, token, dolphinsRestTemplate);
21 | }
22 |
23 | /**
24 | * create schedule
25 | *
26 | * @param projectCode project code
27 | * @param scheduleDefineParam define param
28 | * @return {@link ScheduleInfoResp}
29 | */
30 | public ScheduleInfoResp create(Long projectCode, ScheduleDefineParam scheduleDefineParam) {
31 | String url = dolphinAddress + "/projects/" + projectCode + "/schedules";
32 | log.info("create schedule, url:{}, defineParam:{}", url, scheduleDefineParam);
33 | try {
34 | HttpRestResult restResult =
35 | dolphinsRestTemplate.postForm(
36 | url, getHeader(), scheduleDefineParam, ScheduleInfoResp.class);
37 | if (restResult.getSuccess()) {
38 | return restResult.getData();
39 | } else {
40 | log.error("dolphin scheduler response:{}", restResult);
41 | throw new DolphinException("create dolphin scheduler schedule fail");
42 | }
43 | } catch (Exception e) {
44 | throw new DolphinException("create dolphin scheduler schedule fail", e);
45 | }
46 | }
47 |
48 | /**
49 | * get schedule by workflow
50 | *
51 | * @param projectCode project's code
52 | * @param processDefinitionCode workflow code
53 | * @return {@link List}
54 | */
55 | public List getByWorkflowCode(Long projectCode, Long processDefinitionCode) {
56 | String url = dolphinAddress + "/projects/" + projectCode + "/schedules";
57 | Query query =
58 | new Query()
59 | .addParam("pageNo", "1")
60 | .addParam("pageSize", "10")
61 | .addParam("processDefinitionCode", String.valueOf(processDefinitionCode));
62 | try {
63 | HttpRestResult stringHttpRestResult =
64 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
65 | return JacksonUtils.parseObject(
66 | stringHttpRestResult.getData().toString(),
67 | new TypeReference>() {})
68 | .getTotalList();
69 | } catch (Exception e) {
70 | throw new DolphinException("list dolphin scheduler schedule fail", e);
71 | }
72 | }
73 |
74 | /**
75 | * update schedule
76 | *
77 | * @param projectCode project code
78 | * @param scheduleDefineParam define param
79 | * @return {@link ScheduleInfoResp}
80 | */
81 | public ScheduleInfoResp update(
82 | Long projectCode, Long scheduleId, ScheduleDefineParam scheduleDefineParam) {
83 | String url = dolphinAddress + "/projects/" + projectCode + "/schedules/" + scheduleId;
84 | log.info("update schedule, url:{}, defineParam:{}", url, scheduleDefineParam);
85 | try {
86 | HttpRestResult restResult =
87 | dolphinsRestTemplate.putForm(
88 | url, getHeader(), scheduleDefineParam, ScheduleInfoResp.class);
89 | if (restResult.getSuccess()) {
90 | return restResult.getData();
91 | } else {
92 | log.error("dolphin scheduler response:{}", restResult);
93 | throw new DolphinException("update dolphin scheduler schedule fail");
94 | }
95 | } catch (Exception e) {
96 | throw new DolphinException("update dolphin scheduler schedule fail", e);
97 | }
98 | }
99 |
100 | /**
101 | * online schedule
102 | *
103 | * @param projectCode project code
104 | * @param scheduleId id
105 | * @return true for success,otherwise false
106 | */
107 | public Boolean online(Long projectCode, Long scheduleId) {
108 | String url =
109 | dolphinAddress + "/projects/" + projectCode + "/schedules/" + scheduleId + "/online";
110 | log.info("online schedule, scheduleId:{}, url:{}", scheduleId, url);
111 | try {
112 | HttpRestResult restResult =
113 | dolphinsRestTemplate.postForm(url, getHeader(), null, String.class);
114 | return restResult.getSuccess();
115 | } catch (Exception e) {
116 | throw new DolphinException("online dolphin scheduler schedule fail", e);
117 | }
118 | }
119 |
120 | /**
121 | * offline schedule
122 | *
123 | * @param projectCode project code
124 | * @param scheduleId id
125 | * @return true for success,otherwise false
126 | */
127 | public Boolean offline(Long projectCode, Long scheduleId) {
128 | String url =
129 | dolphinAddress + "/projects/" + projectCode + "/schedules/" + scheduleId + "/offline";
130 | log.info("offline schedule, scheduleId:{}, url:{}", scheduleId, url);
131 | try {
132 | HttpRestResult restResult =
133 | dolphinsRestTemplate.postForm(url, getHeader(), null, String.class);
134 | return restResult.getSuccess();
135 | } catch (Exception e) {
136 | throw new DolphinException("offline dolphin scheduler schedule fail", e);
137 | }
138 | }
139 |
140 | /**
141 | * delete schedule
142 | *
143 | * @param projectCode project code
144 | * @param scheduleId id
145 | * @return true for success,otherwise false
146 | */
147 | public Boolean delete(Long projectCode, Long scheduleId) {
148 | String url = dolphinAddress + "/projects/" + projectCode + "/schedules/" + scheduleId;
149 | log.info("offline schedule, scheduleId:{}, url:{}", scheduleId, url);
150 | try {
151 | HttpRestResult restResult =
152 | dolphinsRestTemplate.delete(url, getHeader(), null, String.class);
153 | return restResult.getSuccess();
154 | } catch (Exception e) {
155 | throw new DolphinException("delete dolphin scheduler schedule fail", e);
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/instance/ProcessInstanceOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.instance;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.github.weaksloth.dolphins.common.PageInfo;
6 | import com.github.weaksloth.dolphins.core.AbstractOperator;
7 | import com.github.weaksloth.dolphins.core.DolphinClientConstant;
8 | import com.github.weaksloth.dolphins.core.DolphinException;
9 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
10 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
11 | import com.github.weaksloth.dolphins.remote.Query;
12 | import com.github.weaksloth.dolphins.util.JacksonUtils;
13 | import java.util.List;
14 | import java.util.Optional;
15 | import lombok.extern.slf4j.Slf4j;
16 |
17 | @Slf4j
18 | public class ProcessInstanceOperator extends AbstractOperator {
19 |
20 | public ProcessInstanceOperator(
21 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
22 | super(dolphinAddress, token, dolphinsRestTemplate);
23 | }
24 |
25 | /**
26 | * start/run process instance
27 | *
28 | * api: /dolphinscheduler/projects/{projectCode}/executors/start-process-instance
29 | *
30 | * @param processInstanceCreateParam process instance create param
31 | * @return true for success,otherwise false
32 | */
33 | public Boolean start(Long projectCode, ProcessInstanceCreateParam processInstanceCreateParam) {
34 | String url = dolphinAddress + "/projects/" + projectCode + "/executors/start-process-instance";
35 | log.info("start process instance ,url:{}", url);
36 | try {
37 | HttpRestResult restResult =
38 | dolphinsRestTemplate.postForm(
39 | url, getHeader(), processInstanceCreateParam, JsonNode.class);
40 | log.info("start process response:{}", restResult);
41 | return restResult.getSuccess();
42 | } catch (Exception e) {
43 | throw new DolphinException("start dolphin scheduler process instance fail", e);
44 | }
45 | }
46 |
47 | /**
48 | * page query process's instance list
49 | *
50 | * @param page page,default 1 while is null
51 | * @param size size,default 10 while is null
52 | * @param projectCode project code
53 | * @param workflowCode workflow id
54 | * @return
55 | */
56 | public List page(
57 | Integer page, Integer size, Long projectCode, Long workflowCode) {
58 | page = Optional.ofNullable(page).orElse(DolphinClientConstant.Page.DEFAULT_PAGE);
59 | size = Optional.ofNullable(size).orElse(DolphinClientConstant.Page.DEFAULT_SIZE);
60 |
61 | String url = dolphinAddress + "/projects/" + projectCode + "/process-instances";
62 |
63 | Query query = new Query();
64 | query
65 | .addParam("pageNo", String.valueOf(page))
66 | .addParam("pageSize", String.valueOf(size))
67 | .addParam("processDefineCode", String.valueOf(workflowCode));
68 |
69 | try {
70 | HttpRestResult restResult =
71 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
72 | return JacksonUtils.parseObject(
73 | restResult.getData().toString(),
74 | new TypeReference>() {})
75 | .getTotalList();
76 | } catch (Exception e) {
77 | throw new DolphinException("page dolphin scheduler process instance list fail", e);
78 | }
79 | }
80 |
81 | /**
82 | * repeat run dolphin scheduler workflow instance
83 | *
84 | * @param projectCode project code
85 | * @param processInstanceId process instance id
86 | * @return true for success,otherwise false
87 | */
88 | public Boolean reRun(Long projectCode, Long processInstanceId) {
89 | log.info("repeat run workflow instance,id:{}", processInstanceId);
90 | return execute(projectCode, processInstanceId, DolphinClientConstant.ExecuteType.RE_RUN);
91 | }
92 |
93 | /**
94 | * stop dolphin scheduler workflow instance
95 | *
96 | * @param projectCode project code
97 | * @param processInstanceId process instance id
98 | * @return true for success,otherwise false
99 | */
100 | public Boolean stop(Long projectCode, Long processInstanceId) {
101 | log.info("stop workflow instance,id:{}", processInstanceId);
102 | return execute(projectCode, processInstanceId, DolphinClientConstant.ExecuteType.STOP);
103 | }
104 |
105 | /**
106 | * pause dolphin scheduler workflow instance
107 | *
108 | * @param projectCode project code
109 | * @param processInstanceId process instance id
110 | * @return true for success,otherwise false
111 | */
112 | public Boolean pause(Long projectCode, Long processInstanceId) {
113 | log.info("stop workflow instance,id:{}", processInstanceId);
114 | return execute(projectCode, processInstanceId, DolphinClientConstant.ExecuteType.PAUSE);
115 | }
116 |
117 | /**
118 | * execute dolphin scheduler workflow instance with custom execute type
119 | *
120 | * @param projectCode project code
121 | * @param processInstanceId process instance id
122 | * @param executeType {@link com.github.weaksloth.dolphins.core.DolphinClientConstant.ExecuteType}
123 | * @return true for success,otherwise false
124 | */
125 | public Boolean execute(Long projectCode, Long processInstanceId, String executeType) {
126 | String url = dolphinAddress + "/projects/" + projectCode + "/executors/execute";
127 | ProcessInstanceRunParam reProcessInstanceRunParam =
128 | new ProcessInstanceRunParam()
129 | .setProcessInstanceId(processInstanceId)
130 | .setExecuteType(executeType);
131 | try {
132 | HttpRestResult restResult =
133 | dolphinsRestTemplate.postForm(url, getHeader(), reProcessInstanceRunParam, String.class);
134 | return restResult.getSuccess();
135 | } catch (Exception e) {
136 | throw new DolphinException(executeType + " dolphin scheduler process instance fail", e);
137 | }
138 | }
139 |
140 | public Boolean delete(Long projectCode, Long processInstanceId) {
141 | String url =
142 | dolphinAddress + "/projects/" + projectCode + "/process-instances/" + processInstanceId;
143 | try {
144 | HttpRestResult restResult =
145 | dolphinsRestTemplate.delete(url, getHeader(), null, String.class);
146 | return restResult.getSuccess();
147 | } catch (Exception e) {
148 | throw new DolphinException("delete dolphin scheduler process instance fail", e);
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/request/DefaultHttpClientRequest.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote.request;
2 |
3 | import com.github.weaksloth.dolphins.remote.BaseHttpMethod;
4 | import com.github.weaksloth.dolphins.remote.Header;
5 | import com.github.weaksloth.dolphins.remote.RequestHttpEntity;
6 | import com.github.weaksloth.dolphins.remote.response.DefaultHttpClientResponse;
7 | import com.github.weaksloth.dolphins.remote.response.HttpClientResponse;
8 | import com.github.weaksloth.dolphins.util.JacksonUtils;
9 | import com.google.common.net.HttpHeaders;
10 | import com.google.common.net.MediaType;
11 | import java.io.File;
12 | import java.io.IOException;
13 | import java.net.URI;
14 | import java.util.*;
15 | import org.apache.http.HttpEntity;
16 | import org.apache.http.HttpEntityEnclosingRequest;
17 | import org.apache.http.NameValuePair;
18 | import org.apache.http.client.config.RequestConfig;
19 | import org.apache.http.client.entity.UrlEncodedFormEntity;
20 | import org.apache.http.client.methods.CloseableHttpResponse;
21 | import org.apache.http.client.methods.HttpRequestBase;
22 | import org.apache.http.entity.ByteArrayEntity;
23 | import org.apache.http.entity.ContentType;
24 | import org.apache.http.entity.StringEntity;
25 | import org.apache.http.entity.mime.HttpMultipartMode;
26 | import org.apache.http.entity.mime.MultipartEntityBuilder;
27 | import org.apache.http.impl.client.CloseableHttpClient;
28 | import org.apache.http.message.BasicNameValuePair;
29 |
30 | public class DefaultHttpClientRequest implements HttpClientRequest {
31 |
32 | private final CloseableHttpClient client;
33 |
34 | private final RequestConfig defaultConfig;
35 |
36 | public DefaultHttpClientRequest(CloseableHttpClient client, RequestConfig defaultConfig) {
37 | this.client = client;
38 | this.defaultConfig = defaultConfig;
39 | }
40 |
41 | @Override
42 | public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity)
43 | throws Exception {
44 | HttpRequestBase request = build(uri, httpMethod, requestHttpEntity);
45 | CloseableHttpResponse closeableHttpResponse = client.execute(request);
46 | return new DefaultHttpClientResponse(closeableHttpResponse);
47 | }
48 |
49 | private HttpRequestBase build(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity)
50 | throws Exception {
51 | Object body = requestHttpEntity.getBody();
52 | BaseHttpMethod method = BaseHttpMethod.of(httpMethod);
53 | Header headers = requestHttpEntity.getHeader();
54 | final HttpRequestBase requestBase = method.init(uri.toString());
55 | this.initRequestHeader(requestBase, headers);
56 | if (MediaType.FORM_DATA.toString().equals(headers.getValue(HttpHeaders.CONTENT_TYPE))) {
57 | // set form data
58 | Map form;
59 | if (requestHttpEntity.ifBodyIsMap()) {
60 | form = requestHttpEntity.castBodyToMap();
61 | } else {
62 | form = requestHttpEntity.bodyToMap();
63 | }
64 |
65 | if (form != null && !form.isEmpty()) {
66 | List params = new ArrayList<>(form.size());
67 | for (Map.Entry entry : form.entrySet()) {
68 | params.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
69 | }
70 | if (requestBase instanceof HttpEntityEnclosingRequest) {
71 | HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
72 | HttpEntity entity = new UrlEncodedFormEntity(params, headers.getCharset());
73 | request.setEntity(entity);
74 | }
75 | }
76 | } else if (ContentType.MULTIPART_FORM_DATA
77 | .getMimeType()
78 | .equals(headers.getValue(HttpHeaders.CONTENT_TYPE))) {
79 |
80 | Map form;
81 | if (requestHttpEntity.ifBodyIsMap()) {
82 | form = requestHttpEntity.castBodyToMap();
83 | } else {
84 | form = requestHttpEntity.bodyToMap();
85 | }
86 |
87 | if (form != null && !form.isEmpty()) {
88 |
89 | MultipartEntityBuilder entityBuilder =
90 | MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
91 |
92 | for (Map.Entry entry : form.entrySet()) {
93 | if (entry.getValue() instanceof File) {
94 | File file = (File) entry.getValue();
95 | entityBuilder.addBinaryBody(
96 | entry.getKey(), file, ContentType.DEFAULT_BINARY, file.getName());
97 | } else {
98 | entityBuilder.addTextBody(
99 | entry.getKey(), entry.getValue().toString(), ContentType.DEFAULT_TEXT);
100 | }
101 | }
102 | if (requestBase instanceof HttpEntityEnclosingRequest) {
103 | HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
104 | HttpEntity entity = entityBuilder.build();
105 | request.setEntity(entity);
106 | }
107 | }
108 |
109 | } else { // set json data
110 | if (requestBase instanceof HttpEntityEnclosingRequest) {
111 | HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
112 | ContentType contentType =
113 | ContentType.create(MediaType.JSON_UTF_8.type(), headers.getCharset());
114 | HttpEntity entity;
115 | if (body instanceof byte[]) {
116 | entity = new ByteArrayEntity((byte[]) body, contentType);
117 | } else {
118 | entity =
119 | new StringEntity(
120 | body instanceof String ? (String) body : JacksonUtils.toJSONString(body),
121 | contentType);
122 | }
123 | request.setEntity(entity);
124 | }
125 | }
126 |
127 | requestBase.setConfig(defaultConfig);
128 | return requestBase;
129 | }
130 |
131 | private void initRequestHeader(HttpRequestBase request, Header headers) {
132 | Iterator> iterator = headers.iterator();
133 | while (iterator.hasNext()) {
134 | Map.Entry entry = iterator.next();
135 |
136 | // we need to remove content-type header when upload file
137 | // otherwise the backend will throw 'Missing initial multi part boundary'
138 | if (entry.getValue().equals(ContentType.MULTIPART_FORM_DATA.getMimeType())) {
139 | continue;
140 | }
141 |
142 | request.setHeader(entry.getKey(), entry.getValue());
143 | }
144 | }
145 |
146 | @Override
147 | public void close() throws IOException {
148 | client.close();
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/remote/DolphinsRestTemplate.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.remote;
2 |
3 | import com.github.weaksloth.dolphins.remote.handler.ResponseHandler;
4 | import com.github.weaksloth.dolphins.remote.request.HttpClientRequest;
5 | import com.github.weaksloth.dolphins.remote.response.HttpClientResponse;
6 | import com.github.weaksloth.dolphins.util.HttpUtils;
7 | import com.google.common.net.MediaType;
8 | import java.net.URI;
9 | import org.apache.http.entity.ContentType;
10 |
11 | /** dolphin scheduler sdk custom rest template,which can support different http client */
12 | public class DolphinsRestTemplate {
13 |
14 | private final HttpClientRequest requestClient;
15 |
16 | public DolphinsRestTemplate(HttpClientRequest requestClient) {
17 | this.requestClient = requestClient;
18 | }
19 |
20 | /**
21 | * http get url request are expanded using the given query
22 | *
23 | * @param url
24 | * @param header
25 | * @param query
26 | * @param responseType
27 | * @param
28 | * @return {@link HttpRestResult}
29 | * @throws Exception
30 | */
31 | public HttpRestResult get(String url, Header header, Query query, Class responseType)
32 | throws Exception {
33 | return execute(url, HttpMethod.GET, new RequestHttpEntity(header, query), responseType);
34 | }
35 |
36 | /**
37 | * @param url
38 | * @param header
39 | * @param body
40 | * @param responseType
41 | * @param
42 | * @return
43 | * @throws Exception
44 | */
45 | public HttpRestResult postForm(
46 | String url, Header header, Object body, Class responseType) throws Exception {
47 | RequestHttpEntity requestHttpEntity =
48 | new RequestHttpEntity(header.setContentType(MediaType.FORM_DATA.toString()), body);
49 | return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
50 | }
51 |
52 | /**
53 | * @param url
54 | * @param header
55 | * @param query
56 | * @param body
57 | * @param responseType
58 | * @param
59 | * @return
60 | * @throws Exception
61 | */
62 | public HttpRestResult postForm(
63 | String url, Header header, Query query, Object body, Class responseType) throws Exception {
64 | RequestHttpEntity requestHttpEntity =
65 | new RequestHttpEntity(header.setContentType(MediaType.FORM_DATA.toString()), query, body);
66 | return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
67 | }
68 |
69 | /**
70 | * post form with file and common param
71 | *
72 | * @param url
73 | * @param header
74 | * @param body
75 | * @param responseType
76 | * @param
77 | * @return
78 | * @throws Exception
79 | */
80 | public HttpRestResult postFileForm(
81 | String url, Header header, Object body, Class responseType) throws Exception {
82 | RequestHttpEntity requestHttpEntity =
83 | new RequestHttpEntity(
84 | header.setContentType(ContentType.MULTIPART_FORM_DATA.getMimeType()), body);
85 | return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
86 | }
87 |
88 | /**
89 | * post request which parameter is json,Content-Type is MediaType.JSON_UTF_8
90 | *
91 | * @param url
92 | * @param header
93 | * @param body
94 | * @param responseType
95 | * @param
96 | * @return
97 | * @throws Exception
98 | */
99 | public HttpRestResult postJson(
100 | String url, Header header, Object body, Class responseType) throws Exception {
101 | RequestHttpEntity requestHttpEntity =
102 | new RequestHttpEntity(header.setContentType(MediaType.JSON_UTF_8.toString()), body);
103 | return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
104 | }
105 |
106 | /**
107 | * post request which parameter is json,Content-Type is MediaType.JSON_UTF_8
108 | *
109 | * @param url
110 | * @param header
111 | * @param query
112 | * @param body
113 | * @param responseType
114 | * @param
115 | * @return
116 | * @throws Exception
117 | */
118 | public HttpRestResult postJson(
119 | String url, Header header, Query query, Object body, Class responseType) throws Exception {
120 | RequestHttpEntity requestHttpEntity =
121 | new RequestHttpEntity(header.setContentType(MediaType.JSON_UTF_8.toString()), query, body);
122 | return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
123 | }
124 |
125 | /**
126 | * @param url
127 | * @param header
128 | * @param body
129 | * @param responseType
130 | * @param
131 | * @return
132 | * @throws Exception
133 | */
134 | public HttpRestResult putForm(
135 | String url, Header header, Object body, Class responseType) throws Exception {
136 | RequestHttpEntity requestHttpEntity =
137 | new RequestHttpEntity(header.setContentType(MediaType.FORM_DATA.toString()), body);
138 | return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
139 | }
140 |
141 | /**
142 | * @param url
143 | * @param header
144 | * @param query
145 | * @param body
146 | * @param responseType
147 | * @param
148 | * @return
149 | * @throws Exception
150 | */
151 | public HttpRestResult putForm(
152 | String url, Header header, Query query, Object body, Class responseType) throws Exception {
153 | RequestHttpEntity requestHttpEntity =
154 | new RequestHttpEntity(header.setContentType(MediaType.FORM_DATA.toString()), query, body);
155 | return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
156 | }
157 |
158 | /**
159 | * post request which parameter is json,Content-Type is MediaType.JSON_UTF_8
160 | *
161 | * @param url
162 | * @param header
163 | * @param body
164 | * @param responseType
165 | * @param
166 | * @return
167 | * @throws Exception
168 | */
169 | public HttpRestResult putJson(
170 | String url, Header header, Object body, Class responseType) throws Exception {
171 | RequestHttpEntity requestHttpEntity =
172 | new RequestHttpEntity(header.setContentType(MediaType.JSON_UTF_8.toString()), body);
173 | return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
174 | }
175 |
176 | /**
177 | * post request which parameter is json,Content-Type is MediaType.JSON_UTF_8
178 | *
179 | * @param url
180 | * @param header
181 | * @param query
182 | * @param body
183 | * @param responseType
184 | * @param
185 | * @return
186 | * @throws Exception
187 | */
188 | public HttpRestResult putJson(
189 | String url, Header header, Query query, Object body, Class responseType) throws Exception {
190 | RequestHttpEntity requestHttpEntity =
191 | new RequestHttpEntity(header.setContentType(MediaType.JSON_UTF_8.toString()), query, body);
192 | return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
193 | }
194 |
195 | /**
196 | * @param url
197 | * @param header
198 | * @param responseType
199 | * @param
200 | * @return
201 | * @throws Exception
202 | */
203 | public HttpRestResult delete(String url, Header header, Query query, Class responseType)
204 | throws Exception {
205 | RequestHttpEntity requestHttpEntity =
206 | new RequestHttpEntity(header.setContentType(MediaType.FORM_DATA.toString()), query);
207 | return execute(url, HttpMethod.DELETE, requestHttpEntity, responseType);
208 | }
209 |
210 | private HttpRestResult execute(
211 | String url, String httpMethod, RequestHttpEntity requestEntity, Class responseType)
212 | throws Exception {
213 | URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
214 |
215 | ResponseHandler responseHandler = new ResponseHandler<>();
216 | responseHandler.setResponseType(responseType);
217 | HttpClientResponse response = null;
218 | try {
219 | response = this.requestClient.execute(uri, httpMethod, requestEntity);
220 | return responseHandler.handle(response);
221 | } finally {
222 | if (response != null) {
223 | response.close();
224 | }
225 | }
226 | }
227 | }
228 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/util/JacksonUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.util;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.core.type.TypeReference;
5 | import com.fasterxml.jackson.databind.JsonNode;
6 | import com.fasterxml.jackson.databind.ObjectMapper;
7 | import com.fasterxml.jackson.databind.node.ArrayNode;
8 | import com.fasterxml.jackson.databind.node.ObjectNode;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.lang.reflect.Type;
12 |
13 | /** json utils based on jackson */
14 | public class JacksonUtils {
15 |
16 | private static final ObjectMapper mapper = new ObjectMapper();
17 |
18 | public static ObjectNode createObjectNode() {
19 | return mapper.createObjectNode();
20 | }
21 |
22 | public static ArrayNode createArrayNode() {
23 | return mapper.createArrayNode();
24 | }
25 |
26 | /**
27 | * parse json string as json node
28 | *
29 | * @param jsonStr json string
30 | * @return {@link JsonNode}
31 | */
32 | public static JsonNode parseNode(String jsonStr) {
33 | try {
34 | return mapper.readTree(jsonStr);
35 | } catch (IOException e) {
36 | throw new RuntimeException("parse json node fail", e);
37 | }
38 | }
39 |
40 | /**
41 | * search json node by path expression
42 | *
43 | * @param jsonNode json node
44 | * @param path path expression, json example: {"k1":{"k2":"v2"},"k3":"v3"},we can get "v2" by path
45 | * "k1.k2", we can get "v3" by path "k3"
46 | * @return
47 | */
48 | private static JsonNode searchJsonNode(JsonNode jsonNode, String path) {
49 | try {
50 | String[] split = path.split("\\.");
51 | for (String key : split) {
52 | jsonNode = jsonNode.get(key);
53 | }
54 | return jsonNode;
55 |
56 | } catch (Exception e) {
57 | throw new IllegalArgumentException("parse json error", e);
58 | }
59 | }
60 |
61 | /**
62 | * @param jsonStr json string
63 | * @param path path expression, json example: {"k1":{"k2":"v2"},"k3":"v3"},we can get "v2" by path
64 | * "k1.k2", we can get "v3" by path "k3"
65 | * @return
66 | */
67 | private static JsonNode searchJsonNode(String jsonStr, String path) {
68 | return searchJsonNode(parseNode(jsonStr), path);
69 | }
70 |
71 | public static ArrayNode getAsArrayNode(String jsonStr, String path) {
72 | JsonNode arrayNode = searchJsonNode(jsonStr, path);
73 | if (!arrayNode.isArray()) {
74 | throw new RuntimeException("path:" + path + " is not a json array");
75 | }
76 | return (ArrayNode) arrayNode;
77 | }
78 |
79 | public static ArrayNode getAsArrayNode(JsonNode jsonNode, String path) {
80 | JsonNode arrayNode = searchJsonNode(jsonNode, path);
81 | if (!arrayNode.isArray()) {
82 | throw new RuntimeException("path:" + path + " is not a json array");
83 | }
84 | return (ArrayNode) arrayNode;
85 | }
86 |
87 | /**
88 | * get value as string
89 | *
90 | * @param jsonStr json string
91 | * @param path path expression
92 | * @return
93 | */
94 | public static String getAsText(String jsonStr, String path) {
95 | return searchJsonNode(jsonStr, path).textValue();
96 | }
97 |
98 | /**
99 | * get value as string
100 | *
101 | * @param jsonNode json node
102 | * @param path path expression
103 | * @return
104 | */
105 | public static String getAsText(JsonNode jsonNode, String path) {
106 | return searchJsonNode(jsonNode, path).textValue();
107 | }
108 |
109 | /**
110 | * get value as long
111 | *
112 | * @param jsonStr json string
113 | * @param path path expression
114 | * @return
115 | */
116 | public static Long getAsLong(String jsonStr, String path) {
117 | return searchJsonNode(jsonStr, path).longValue();
118 | }
119 |
120 | /**
121 | * get value as long
122 | *
123 | * @param jsonNode json node
124 | * @param path path expression
125 | * @return
126 | */
127 | public static Long getAsLong(JsonNode jsonNode, String path) {
128 | return searchJsonNode(jsonNode, path).longValue();
129 | }
130 |
131 | /**
132 | * get value as int
133 | *
134 | * @param jsonStr json string
135 | * @param path path expression
136 | * @return
137 | */
138 | public static Integer getAsInteger(String jsonStr, String path) {
139 | return searchJsonNode(jsonStr, path).intValue();
140 | }
141 |
142 | /**
143 | * get value as int
144 | *
145 | * @param jsonNode json node
146 | * @param path path expression
147 | * @return
148 | */
149 | public static Integer getAsInteger(JsonNode jsonNode, String path) {
150 | return searchJsonNode(jsonNode, path).intValue();
151 | }
152 |
153 | /**
154 | * get value as boolean
155 | *
156 | * @param jsonStr json string
157 | * @param path path expression
158 | * @return
159 | */
160 | public static Boolean getAsBoolean(String jsonStr, String path) {
161 | return searchJsonNode(jsonStr, path).booleanValue();
162 | }
163 |
164 | /**
165 | * get value as boolean
166 | *
167 | * @param jsonNode json node
168 | * @param path path expression
169 | * @return
170 | */
171 | public static Boolean getAsBoolean(JsonNode jsonNode, String path) {
172 | return searchJsonNode(jsonNode, path).booleanValue();
173 | }
174 |
175 | public static String toJSONString(Object object) {
176 | try {
177 | return mapper.writeValueAsString(object);
178 | } catch (JsonProcessingException e) {
179 | throw new RuntimeException("transfer to json string fail", e);
180 | }
181 | }
182 |
183 | /**
184 | * @param json json str
185 | * @param clazz target class
186 | * @param
187 | * @return
188 | */
189 | public static T parseObject(String json, Class clazz) {
190 | try {
191 | return mapper.readValue(json, clazz);
192 | } catch (IOException e) {
193 | throw new RuntimeException("json parse object fail", e);
194 | }
195 | }
196 |
197 | /**
198 | * @param json json string
199 | * @param typeReference type of object
200 | * @param
201 | * @return
202 | */
203 | public static T parseObject(String json, TypeReference typeReference) {
204 | try {
205 | return mapper.readValue(json, typeReference);
206 | } catch (IOException e) {
207 | throw new RuntimeException("json parse object fail", e);
208 | }
209 | }
210 |
211 | /**
212 | * Json string deserialize to Object.
213 | *
214 | * @param json json string
215 | * @param type {@link Type} of object
216 | * @param General type
217 | * @return object
218 | * @throws RuntimeException if deserialize failed
219 | */
220 | public static T parseObject(String json, Type type) {
221 | try {
222 | return mapper.readValue(json, mapper.constructType(type));
223 | } catch (IOException e) {
224 | throw new RuntimeException("json parse object fail", e);
225 | }
226 | }
227 |
228 | /**
229 | * Json string deserialize to Object.
230 | *
231 | * @param inputStream json string input stream
232 | * @param type {@link Type} of object
233 | * @param General type
234 | * @return object
235 | * @throws RuntimeException if deserialize failed
236 | */
237 | public static T parseObject(InputStream inputStream, Type type) {
238 | try {
239 | return mapper.readValue(inputStream, mapper.constructType(type));
240 | } catch (IOException e) {
241 | throw new RuntimeException(e);
242 | }
243 | }
244 |
245 | /**
246 | * Json string deserialize to Object.
247 | *
248 | * @param inputStream json string input stream
249 | * @param typeReference {@link Type} of object
250 | * @param General type
251 | * @return object
252 | * @throws RuntimeException if deserialize failed
253 | */
254 | public static T parseObject(InputStream inputStream, TypeReference typeReference) {
255 | try {
256 | return mapper.readValue(inputStream, typeReference);
257 | } catch (IOException e) {
258 | throw new RuntimeException(e);
259 | }
260 | }
261 |
262 | public static ObjectMapper getObjectMapper() {
263 | return mapper;
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/src/main/java/com/github/weaksloth/dolphins/process/ProcessOperator.java:
--------------------------------------------------------------------------------
1 | package com.github.weaksloth.dolphins.process;
2 |
3 | import com.fasterxml.jackson.core.type.TypeReference;
4 | import com.fasterxml.jackson.databind.JsonNode;
5 | import com.github.weaksloth.dolphins.common.PageInfo;
6 | import com.github.weaksloth.dolphins.core.AbstractOperator;
7 | import com.github.weaksloth.dolphins.core.DolphinClientConstant;
8 | import com.github.weaksloth.dolphins.core.DolphinException;
9 | import com.github.weaksloth.dolphins.remote.DolphinsRestTemplate;
10 | import com.github.weaksloth.dolphins.remote.HttpRestResult;
11 | import com.github.weaksloth.dolphins.remote.Query;
12 | import com.github.weaksloth.dolphins.util.JacksonUtils;
13 | import java.util.List;
14 | import java.util.Optional;
15 | import lombok.extern.slf4j.Slf4j;
16 |
17 | @Slf4j
18 | public class ProcessOperator extends AbstractOperator {
19 |
20 | public ProcessOperator(
21 | String dolphinAddress, String token, DolphinsRestTemplate dolphinsRestTemplate) {
22 | super(dolphinAddress, token, dolphinsRestTemplate);
23 | }
24 |
25 | /**
26 | * page query process define(workflow)
27 | *
28 | * @param projectCode project code
29 | * @param page page
30 | * @param size size
31 | * @param searchVal process name
32 | * @return list
33 | */
34 | public List page(
35 | Long projectCode, Integer page, Integer size, String searchVal) {
36 | page = Optional.ofNullable(page).orElse(DolphinClientConstant.Page.DEFAULT_PAGE);
37 | size = Optional.ofNullable(size).orElse(DolphinClientConstant.Page.DEFAULT_SIZE);
38 | searchVal = Optional.ofNullable(searchVal).orElse("");
39 |
40 | String url = dolphinAddress + "/projects/" + projectCode + "/process-definition";
41 | Query query =
42 | new Query()
43 | .addParam("pageNo", String.valueOf(page))
44 | .addParam("pageSize", String.valueOf(size))
45 | .addParam("searchVal", searchVal);
46 |
47 | try {
48 | HttpRestResult restResult =
49 | dolphinsRestTemplate.get(url, getHeader(), query, JsonNode.class);
50 |
51 | return JacksonUtils.parseObject(
52 | restResult.getData().toString(), new TypeReference>() {})
53 | .getTotalList();
54 | } catch (Exception e) {
55 | throw new DolphinException("list dolphin scheduler workflow fail", e);
56 | }
57 | }
58 |
59 | /**
60 | * create dolphin scheduler process api:
61 | * /dolphinscheduler/projects/{projectCode}/process-definition
62 | *
63 | * @param projectCode project code
64 | * @param processDefineParam create process param
65 | * @return create response
66 | */
67 | public ProcessDefineResp create(Long projectCode, ProcessDefineParam processDefineParam) {
68 | String url = dolphinAddress + "/projects/" + projectCode + "/process-definition";
69 | log.info(
70 | "create process definition, url:{}, param:{}",
71 | url,
72 | JacksonUtils.toJSONString(processDefineParam));
73 | try {
74 | HttpRestResult restResult =
75 | dolphinsRestTemplate.postForm(
76 | url, getHeader(), processDefineParam, ProcessDefineResp.class);
77 | if (restResult.getSuccess()) {
78 | return restResult.getData();
79 | } else {
80 | log.error("dolphin scheduler response:{}", restResult);
81 | throw new DolphinException("create dolphin scheduler workflow fail");
82 | }
83 | } catch (Exception e) {
84 | throw new DolphinException("create dolphin scheduler workflow fail", e);
85 | }
86 | }
87 |
88 | /**
89 | * update dolphin scheduler workflow
90 | *
91 | * api:/dolphinscheduler/projects/{projectCode}/process-definition/{process-definition-code}
92 | *
93 | * @param processDefineParam update process def param
94 | * @param processCode workflow code
95 | * @return update response json
96 | */
97 | public ProcessDefineResp update(
98 | Long projectCode, ProcessDefineParam processDefineParam, Long processCode) {
99 | String url = dolphinAddress + "/projects/" + projectCode + "/process-definition/" + processCode;
100 | log.info("update process definition, url:{}, param:{}", url, processDefineParam);
101 | try {
102 | HttpRestResult restResult =
103 | dolphinsRestTemplate.putForm(
104 | url, getHeader(), processDefineParam, ProcessDefineResp.class);
105 | if (restResult.getSuccess()) {
106 | return restResult.getData();
107 | } else {
108 | log.error("dolphin scheduler response:{}", restResult);
109 | throw new DolphinException("update dolphin scheduler workflow fail");
110 | }
111 | } catch (Exception e) {
112 | throw new DolphinException("update dolphin scheduler workflow fail", e);
113 | }
114 | }
115 |
116 | /**
117 | * delete process
118 | *
119 | * @param projectCode project code
120 | * @param processCode process code
121 | * @return true for success,otherwise false
122 | */
123 | public Boolean delete(Long projectCode, Long processCode) {
124 | String url = dolphinAddress + "/projects/" + projectCode + "/process-definition/" + processCode;
125 | log.info("delete process definition,processCode:{}, url:{}", processCode, url);
126 | try {
127 | HttpRestResult restResult =
128 | dolphinsRestTemplate.delete(url, getHeader(), null, String.class);
129 | return restResult.getSuccess();
130 | } catch (Exception e) {
131 | throw new DolphinException("delete dolphin scheduler workflow fail", e);
132 | }
133 | }
134 |
135 | /**
136 | * release, api: /dolphinscheduler/projects/{projectCode}/process-definition/{code}/release
137 | *
138 | * @param projectCode project code
139 | * @param code workflow id
140 | * @param processReleaseParam param
141 | * @return true for success,otherwise false
142 | */
143 | public Boolean release(Long projectCode, Long code, ProcessReleaseParam processReleaseParam) {
144 | String url =
145 | dolphinAddress + "/projects/" + projectCode + "/process-definition/" + code + "/release";
146 | log.info("release process definition,url:{}, param:{}", url, processReleaseParam);
147 | try {
148 | HttpRestResult restResult =
149 | dolphinsRestTemplate.postForm(url, getHeader(), processReleaseParam, String.class);
150 | return restResult.getSuccess();
151 | } catch (Exception e) {
152 | throw new DolphinException("release dolphin scheduler workflow fail", e);
153 | }
154 | }
155 |
156 | /**
157 | * online workflow, this method can replace {@link #release(Long, Long, ProcessReleaseParam)}
158 | *
159 | * @param projectCode project code
160 | * @param code workflow id
161 | * @return true for success,otherwise false
162 | */
163 | public Boolean online(Long projectCode, Long code) {
164 | return release(projectCode, code, ProcessReleaseParam.newOnlineInstance());
165 | }
166 |
167 | /**
168 | * offline workflow, this method can replace {@link #release(Long, Long, ProcessReleaseParam)}
169 | *
170 | * @param projectCode project code
171 | * @param code workflow id
172 | * @return true for success,otherwise false
173 | */
174 | public Boolean offline(Long projectCode, Long code) {
175 | return release(projectCode, code, ProcessReleaseParam.newOfflineInstance());
176 | }
177 |
178 | /**
179 | * generate task code
180 | *
181 | * @param projectCode project's code
182 | * @param codeNumber the number of task code
183 | * @return task code list
184 | */
185 | public List generateTaskCode(Long projectCode, int codeNumber) {
186 | String url = dolphinAddress + "/projects/" + projectCode + "/task-definition/gen-task-codes";
187 | Query query = new Query();
188 | query.addParam("genNum", String.valueOf(codeNumber));
189 | try {
190 | HttpRestResult restResult =
191 | dolphinsRestTemplate.get(url, getHeader(), query, List.class);
192 | return (List) restResult.getData();
193 | } catch (Exception e) {
194 | throw new DolphinException("generate task code fail", e);
195 | }
196 | }
197 | }
198 |
--------------------------------------------------------------------------------