├── doc └── images │ ├── condition.png │ ├── shell_task.png │ └── simple_workflow.png ├── src ├── main │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── weaksloth │ │ │ └── dolphins │ │ │ ├── enums │ │ │ ├── ServerStatus.java │ │ │ ├── AlertEvent.java │ │ │ ├── AlertWarnLevel.java │ │ │ ├── SlotCheckState.java │ │ │ ├── ResourceManagerType.java │ │ │ ├── ResUploadType.java │ │ │ ├── TaskEventType.java │ │ │ ├── ProgramType.java │ │ │ ├── HttpMethod.java │ │ │ ├── HttpParametersType.java │ │ │ ├── TaskRecordStatus.java │ │ │ ├── CycleEnum.java │ │ │ ├── HttpCheckCondition.java │ │ │ ├── BlockingOpportunity.java │ │ │ ├── ProfileType.java │ │ │ ├── SqoopJobType.java │ │ │ ├── AlertPluginInstanceType.java │ │ │ ├── SqoopQueryType.java │ │ │ ├── DbConnectType.java │ │ │ ├── TimeoutFlag.java │ │ │ ├── TaskExecuteType.java │ │ │ ├── ApiTriggerType.java │ │ │ ├── UserType.java │ │ │ ├── Flag.java │ │ │ ├── CacheType.java │ │ │ ├── RunMode.java │ │ │ ├── ComplementDependentMode.java │ │ │ ├── FailureStrategy.java │ │ │ ├── ExecutionOrder.java │ │ │ ├── Priority.java │ │ │ ├── TaskDependType.java │ │ │ ├── AlertStatus.java │ │ │ ├── UdfType.java │ │ │ ├── StateEventType.java │ │ │ ├── ReleaseState.java │ │ │ ├── ConditionType.java │ │ │ ├── TaskGroupQueueStatus.java │ │ │ ├── AuditOperationType.java │ │ │ ├── AuditResourceType.java │ │ │ ├── PluginType.java │ │ │ ├── AlertType.java │ │ │ ├── DbTypeEnum.java │ │ │ ├── WarningType.java │ │ │ ├── ListenerEventType.java │ │ │ ├── AuthorizationType.java │ │ │ ├── ProcessExecutionTypeEnum.java │ │ │ ├── CommandType.java │ │ │ └── WorkflowExecutionStatus.java │ │ │ ├── task │ │ │ ├── ConditionTask.java │ │ │ ├── AbstractTask.java │ │ │ ├── ShellTask.java │ │ │ ├── ProcedureTask.java │ │ │ ├── TaskResource.java │ │ │ ├── PythonTask.java │ │ │ ├── SqlTask.java │ │ │ ├── DataxTask.java │ │ │ ├── SparkTask.java │ │ │ └── HttpTask.java │ │ │ ├── instance │ │ │ ├── ProcessInstanceRunParam.java │ │ │ ├── ProcessInstanceCreateParam.java │ │ │ ├── ProcessInstanceQueryResp.java │ │ │ └── ProcessInstanceOperator.java │ │ │ ├── core │ │ │ ├── DolphinException.java │ │ │ ├── AbstractOperator.java │ │ │ ├── DolphinClientConstant.java │ │ │ └── DolphinClient.java │ │ │ ├── project │ │ │ ├── ProjectUpdateParam.java │ │ │ ├── ProjectCreateParam.java │ │ │ ├── ProjectInfoResp.java │ │ │ └── ProjectOperator.java │ │ │ ├── remote │ │ │ ├── response │ │ │ │ ├── HttpClientResponse.java │ │ │ │ └── DefaultHttpClientResponse.java │ │ │ ├── request │ │ │ │ ├── HttpClientRequest.java │ │ │ │ └── DefaultHttpClientRequest.java │ │ │ ├── HttpMethod.java │ │ │ ├── HttpRestResult.java │ │ │ ├── TypeReferenceHttpResult.java │ │ │ ├── handler │ │ │ │ └── ResponseHandler.java │ │ │ ├── Query.java │ │ │ ├── BaseHttpMethod.java │ │ │ ├── HttpClientFactory.java │ │ │ ├── RequestHttpEntity.java │ │ │ ├── Header.java │ │ │ └── DolphinsRestTemplate.java │ │ │ ├── tenant │ │ │ ├── TenantDefineParam.java │ │ │ ├── TenantInfoResp.java │ │ │ └── TenantOperator.java │ │ │ ├── resource │ │ │ ├── ResourceUpdateParam.java │ │ │ ├── ResourceUploadParam.java │ │ │ ├── ResourceCreateParam.java │ │ │ ├── ResourceQueryRes.java │ │ │ └── ResourceOperator.java │ │ │ ├── util │ │ │ ├── HttpUtils.java │ │ │ ├── TaskRelationUtils.java │ │ │ ├── TaskLocationUtils.java │ │ │ ├── TaskUtils.java │ │ │ ├── TaskDefinitionUtils.java │ │ │ └── JacksonUtils.java │ │ │ ├── datasource │ │ │ ├── DataSourceUpdateParam.java │ │ │ ├── DataSourceCreateParam.java │ │ │ ├── DataSourceQueryResp.java │ │ │ └── DataSourceOperator.java │ │ │ ├── process │ │ │ ├── TaskLocation.java │ │ │ ├── TaskRelation.java │ │ │ ├── ProcessReleaseParam.java │ │ │ ├── Parameter.java │ │ │ ├── TaskDefinition.java │ │ │ ├── ProcessDefineResp.java │ │ │ ├── ProcessDefineParam.java │ │ │ └── ProcessOperator.java │ │ │ ├── schedule │ │ │ ├── ScheduleDefineParam.java │ │ │ ├── ScheduleInfoResp.java │ │ │ └── ScheduleOperator.java │ │ │ ├── common │ │ │ └── PageInfo.java │ │ │ └── taskinstance │ │ │ ├── TaskInstanceOperator.java │ │ │ └── TaskInstanceQueryResp.java │ └── resources │ │ └── logback.xml └── test │ └── java │ └── com │ └── github │ └── weaksloth │ └── dolphins │ ├── utils │ └── TaskLocationUtilsTest.java │ ├── taskinstance │ └── TaskInstanceTest.java │ ├── BaseTest.java │ ├── tenant │ └── TenantTest.java │ ├── project │ └── ProjectTest.java │ ├── insatnce │ └── ProcessInstanceTest.java │ ├── schedule │ └── ScheduleTest.java │ ├── datasource │ └── DataSourceTest.java │ ├── resource │ └── ResourceTest.java │ └── workflow │ └── WorkflowTest.java ├── .gitignore └── pom.xml /doc/images/condition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weaksloth/dolphinscheduler-sdk-java/HEAD/doc/images/condition.png -------------------------------------------------------------------------------- /doc/images/shell_task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weaksloth/dolphinscheduler-sdk-java/HEAD/doc/images/shell_task.png -------------------------------------------------------------------------------- /doc/images/simple_workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weaksloth/dolphinscheduler-sdk-java/HEAD/doc/images/simple_workflow.png -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/ServerStatus.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum ServerStatus { 4 | NORMAL, 5 | BUSY 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/AlertEvent.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum AlertEvent { 4 | SERVER_DOWN, 5 | TIME_OUT 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/AlertWarnLevel.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum AlertWarnLevel { 4 | MIDDLE, 5 | SERIOUS 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/SlotCheckState.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum SlotCheckState { 4 | PASS, 5 | INJECT, 6 | CHANGE 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/ResourceManagerType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum ResourceManagerType { 4 | YARN, 5 | 6 | KUBERNETES; 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/ResUploadType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** data base types */ 4 | public enum ResUploadType { 5 | LOCAL, 6 | HDFS, 7 | S3, 8 | OSS, 9 | GCS, 10 | ABS, 11 | OBS 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/TaskEventType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum TaskEventType { 4 | DISPATCH, 5 | DELAY, 6 | RUNNING, 7 | RESULT, 8 | UPDATE_PID, 9 | WORKER_REJECT, 10 | CACHE, 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/ProgramType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** support program types */ 4 | public enum ProgramType { 5 | /** 0 JAVA,1 SCALA,2 PYTHON,3 SQL */ 6 | JAVA, 7 | SCALA, 8 | PYTHON, 9 | SQL 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/HttpMethod.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** http method */ 4 | public enum HttpMethod { 5 | /** 0 get 1 post 2 head 3 put 4 delete */ 6 | GET, 7 | POST, 8 | HEAD, 9 | PUT, 10 | DELETE 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/HttpParametersType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** http parameters type */ 4 | public enum HttpParametersType { 5 | /** 0 parameter; 1 body; 2 headers; */ 6 | PARAMETER, 7 | BODY, 8 | HEADERS 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/TaskRecordStatus.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** task record status */ 4 | public enum TaskRecordStatus { 5 | 6 | /** status: 0 success 1 failure 2 exception */ 7 | SUCCESS, 8 | FAILURE, 9 | EXCEPTION 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/CycleEnum.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** cycle enums */ 4 | public enum CycleEnum { 5 | /** 0 minute; 1 hour; 2 day; 3 week; 4 month; 5 year; */ 6 | MINUTE, 7 | HOUR, 8 | DAY, 9 | WEEK, 10 | MONTH, 11 | YEAR 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/task/ConditionTask.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.task; 2 | 3 | import lombok.Data; 4 | import lombok.experimental.Accessors; 5 | 6 | @Data 7 | @Accessors(chain = true) 8 | public class ConditionTask extends AbstractTask { 9 | 10 | @Override 11 | public String getTaskType() { 12 | return "CONDITIONS"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/HttpCheckCondition.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** http check condition */ 4 | public enum HttpCheckCondition { 5 | /** 0 status_code_default:200 1 status_code_custom 2 body_contains 3 body_not_contains */ 6 | STATUS_CODE_DEFAULT, 7 | STATUS_CODE_CUSTOM, 8 | BODY_CONTAINS, 9 | BODY_NOT_CONTAINS 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/instance/ProcessInstanceRunParam.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.instance; 2 | 3 | import lombok.Data; 4 | import lombok.experimental.Accessors; 5 | 6 | /** re run/recover process instance */ 7 | @Data 8 | @Accessors(chain = true) 9 | public class ProcessInstanceRunParam { 10 | 11 | private Long processInstanceId; 12 | 13 | private String executeType; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/core/DolphinException.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.core; 2 | 3 | public class DolphinException extends RuntimeException { 4 | 5 | public DolphinException() { 6 | super(); 7 | } 8 | 9 | public DolphinException(String message) { 10 | super(message); 11 | } 12 | 13 | public DolphinException(String message, Throwable e) { 14 | super(message, e); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/project/ProjectUpdateParam.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.project; 2 | 3 | import lombok.Data; 4 | import lombok.experimental.Accessors; 5 | 6 | @Data 7 | @Accessors(chain = true) 8 | public class ProjectUpdateParam { 9 | 10 | private Long projectCode; 11 | 12 | private String projectName; 13 | 14 | private String description; 15 | 16 | private String userName; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/BlockingOpportunity.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum BlockingOpportunity { 4 | BLOCKING_ON_SUCCESS("BlockingOnSuccess"), 5 | BLOCKING_ON_FAILED("BlockingOnFailed"); 6 | 7 | private final String desc; 8 | 9 | BlockingOpportunity(String desc) { 10 | this.desc = desc; 11 | } 12 | 13 | public String getDesc() { 14 | return desc; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/project/ProjectCreateParam.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.project; 2 | 3 | import lombok.Data; 4 | import lombok.experimental.Accessors; 5 | 6 | /** create project param */ 7 | @Data 8 | @Accessors(chain = true) 9 | public class ProjectCreateParam { 10 | 11 | /** project name */ 12 | private String projectName; 13 | 14 | /** project description */ 15 | private String description; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/remote/response/HttpClientResponse.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.remote.response; 2 | 3 | import java.io.Closeable; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.util.Map; 7 | 8 | public interface HttpClientResponse extends Closeable { 9 | 10 | Map getHeaders(); 11 | 12 | InputStream getBody() throws IOException; 13 | 14 | int getStatusCode(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/ProfileType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | import com.google.common.collect.Lists; 4 | import java.util.List; 5 | 6 | public enum ProfileType { 7 | ; 8 | 9 | public static final String H2 = "h2"; 10 | 11 | public static final String MYSQL = "mysql"; 12 | 13 | public static final String POSTGRESQL = "postgresql"; 14 | 15 | public static final List DATASOURCE_PROFILE = Lists.newArrayList(H2, MYSQL, POSTGRESQL); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/tenant/TenantDefineParam.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.tenant; 2 | 3 | import lombok.Data; 4 | import lombok.experimental.Accessors; 5 | 6 | /** create or update tenant param */ 7 | @Data 8 | @Accessors(chain = true) 9 | public class TenantDefineParam { 10 | 11 | private String tenantCode; 12 | 13 | /** the default queue id is 1, which means default in dolphin scheduler */ 14 | private Integer queueId = 1; 15 | 16 | private String description; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/resource/ResourceUpdateParam.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.resource; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.experimental.Accessors; 7 | 8 | @Data 9 | @Accessors(chain = true) 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class ResourceUpdateParam { 13 | 14 | private String tenantCode; 15 | 16 | private String fullName; 17 | 18 | private String content; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/SqoopJobType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum SqoopJobType { 4 | CUSTOM(0, "CUSTOM"), 5 | TEMPLATE(1, "TEMPLATE"); 6 | 7 | SqoopJobType(int code, String descp) { 8 | this.code = code; 9 | this.descp = descp; 10 | } 11 | 12 | private final int code; 13 | private final String descp; 14 | 15 | public int getCode() { 16 | return code; 17 | } 18 | 19 | public String getDescp() { 20 | return descp; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/remote/request/HttpClientRequest.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.remote.request; 2 | 3 | import com.github.weaksloth.dolphins.remote.RequestHttpEntity; 4 | import com.github.weaksloth.dolphins.remote.response.HttpClientResponse; 5 | import java.io.Closeable; 6 | import java.net.URI; 7 | 8 | public interface HttpClientRequest extends Closeable { 9 | 10 | HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity) 11 | throws Exception; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/AlertPluginInstanceType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum AlertPluginInstanceType { 4 | NORMAL(0, "NORMAL"), 5 | GLOBAL(1, "GLOBAL"); 6 | 7 | AlertPluginInstanceType(int code, String descp) { 8 | this.code = code; 9 | this.descp = descp; 10 | } 11 | 12 | private final int code; 13 | private final String descp; 14 | 15 | public int getCode() { 16 | return code; 17 | } 18 | 19 | public String getDescp() { 20 | return descp; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/SqoopQueryType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum SqoopQueryType { 4 | FORM(0, "SQOOP_QUERY_FORM"), 5 | SQL(1, "SQOOP_QUERY_SQL"); 6 | 7 | private final Integer code; 8 | 9 | private final String desc; 10 | 11 | SqoopQueryType(Integer code, String desc) { 12 | this.code = code; 13 | this.desc = desc; 14 | } 15 | 16 | public Integer getCode() { 17 | return code; 18 | } 19 | 20 | public String getDesc() { 21 | return desc; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/DbConnectType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum DbConnectType { 4 | ORACLE_SERVICE_NAME(0, "Oracle Service Name"), 5 | ORACLE_SID(1, "Oracle SID"); 6 | 7 | DbConnectType(int code, String descp) { 8 | this.code = code; 9 | this.descp = descp; 10 | } 11 | 12 | private final int code; 13 | 14 | private final String descp; 15 | 16 | public int getCode() { 17 | return code; 18 | } 19 | 20 | public String getDescp() { 21 | return descp; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/TimeoutFlag.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** timeout flag */ 4 | public enum TimeoutFlag { 5 | 6 | /** 0 close 1 open */ 7 | CLOSE(0, "close"), 8 | OPEN(1, "open"); 9 | 10 | TimeoutFlag(int code, String desc) { 11 | this.code = code; 12 | this.desc = desc; 13 | } 14 | 15 | private final int code; 16 | private final String desc; 17 | 18 | public int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDesc() { 23 | return desc; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/remote/HttpMethod.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.remote; 2 | 3 | public class HttpMethod { 4 | 5 | public static final String GET = "GET"; 6 | 7 | public static final String HEAD = "HEAD"; 8 | 9 | public static final String POST = "POST"; 10 | 11 | public static final String PUT = "PUT"; 12 | 13 | public static final String PATCH = "PATCH"; 14 | 15 | public static final String DELETE = "DELETE"; 16 | 17 | public static final String OPTIONS = "OPTIONS"; 18 | 19 | public static final String TRACE = "TRACE"; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/remote/HttpRestResult.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.remote; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * dolphin scheduler rest api response result 9 | * 10 | * @param 11 | */ 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class HttpRestResult { 16 | 17 | private Integer code; 18 | 19 | private String msg; 20 | 21 | private T data; 22 | 23 | private Boolean success; 24 | 25 | private Boolean failed; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/TaskExecuteType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** task execute type */ 4 | public enum TaskExecuteType { 5 | 6 | /** 0 batch 1 stream */ 7 | BATCH(0, "batch"), 8 | STREAM(1, "stream"); 9 | 10 | TaskExecuteType(int code, String desc) { 11 | this.code = code; 12 | this.desc = desc; 13 | } 14 | 15 | private final int code; 16 | private final String desc; 17 | 18 | public int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDesc() { 23 | return desc; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/ApiTriggerType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** trigger support type */ 4 | public enum ApiTriggerType { 5 | PROCESS(0, "process instance"), 6 | TASK(1, "task node"), 7 | COMMAND(2, "command"); 8 | 9 | ApiTriggerType(int code, String desc) { 10 | this.code = code; 11 | this.desc = desc; 12 | } 13 | 14 | private final int code; 15 | private final String desc; 16 | 17 | public int getCode() { 18 | return code; 19 | } 20 | 21 | public String getDesc() { 22 | return desc; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/UserType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** user type */ 4 | public enum UserType { 5 | 6 | /** 0 admin user; 1 general user */ 7 | ADMIN_USER(0, "admin user"), 8 | GENERAL_USER(1, "general user"); 9 | 10 | UserType(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 int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDescp() { 23 | return descp; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/Flag.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** have_script have_file can_retry have_arr_variables have_map_variables have_alert is_cache */ 4 | public enum Flag { 5 | 6 | /** 0 no 1 yes */ 7 | NO(0, "no"), 8 | YES(1, "yes"); 9 | 10 | Flag(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 int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDescp() { 23 | return descp; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/CacheType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum CacheType { 4 | TENANT("tenant"), 5 | USER("user"), 6 | QUEUE("queue"), 7 | PROCESS_DEFINITION("processDefinition"), 8 | PROCESS_TASK_RELATION("processTaskRelation"), 9 | TASK_DEFINITION("taskDefinition"), 10 | WORKER_GROUP("workerGroup"), 11 | SCHEDULE("schedule"); 12 | 13 | CacheType(String cacheName) { 14 | this.cacheName = cacheName; 15 | } 16 | 17 | private final String cacheName; 18 | 19 | public String getCacheName() { 20 | return cacheName; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/RunMode.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** complement data run mode */ 4 | public enum RunMode { 5 | 6 | /** 0 serial run 1 parallel run */ 7 | RUN_MODE_SERIAL(0, "serial run"), 8 | RUN_MODE_PARALLEL(1, "parallel run"); 9 | 10 | RunMode(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 int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDescp() { 23 | return descp; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/resource/ResourceUploadParam.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.resource; 2 | 3 | import com.github.weaksloth.dolphins.core.DolphinClientConstant; 4 | import java.io.File; 5 | import lombok.Data; 6 | import lombok.experimental.Accessors; 7 | 8 | @Data 9 | @Accessors(chain = true) 10 | public class ResourceUploadParam { 11 | 12 | private String type = DolphinClientConstant.Resource.TYPE_FILE; 13 | 14 | private String currentDir = DolphinClientConstant.Resource.DEFAULT_CURRENT_DIR; 15 | 16 | private String description; 17 | 18 | private File file; 19 | 20 | private String name; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/util/HttpUtils.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.util; 2 | 3 | import com.github.weaksloth.dolphins.remote.Query; 4 | import java.net.URI; 5 | import java.net.URISyntaxException; 6 | 7 | public class HttpUtils { 8 | 9 | /** 10 | * build URI By url and query. 11 | * 12 | * @param url url 13 | * @param query query param {@link Query} 14 | * @return {@link URI} 15 | */ 16 | public static URI buildUri(String url, Query query) throws URISyntaxException { 17 | if (query != null && !query.isEmpty()) { 18 | url = url + "?" + query.toQueryUrl(); 19 | } 20 | return new URI(url); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/ComplementDependentMode.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** task node depend type */ 4 | public enum ComplementDependentMode { 5 | 6 | /** 0 off mode 1 run complement data with all dependent process */ 7 | OFF_MODE(0, "off mode"), 8 | ALL_DEPENDENT(1, "all dependent"); 9 | 10 | ComplementDependentMode(int code, String desc) { 11 | this.code = code; 12 | this.desc = desc; 13 | } 14 | 15 | private final int code; 16 | private final String desc; 17 | 18 | public int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDesc() { 23 | return desc; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/FailureStrategy.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** failure policy when some task node failed. */ 4 | public enum FailureStrategy { 5 | 6 | /** 0 ending process when some tasks failed. 1 continue running when some tasks failed. */ 7 | END(0, "end"), 8 | CONTINUE(1, "continue"); 9 | 10 | FailureStrategy(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 int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDescp() { 23 | return descp; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/ExecutionOrder.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** complement data in some kind of order */ 4 | public enum ExecutionOrder { 5 | 6 | /** 0 complement data in descending order 1 complement data in ascending order */ 7 | DESC_ORDER(0, "descending order"), 8 | ASC_ORDER(1, "ascending order"); 9 | 10 | ExecutionOrder(int code, String desc) { 11 | this.code = code; 12 | this.desc = desc; 13 | } 14 | 15 | private final int code; 16 | private final String desc; 17 | 18 | public int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDesc() { 23 | return desc; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/task/AbstractTask.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.task; 2 | 3 | import com.fasterxml.jackson.databind.node.ObjectNode; 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 abstract class AbstractTask { 11 | 12 | protected ObjectNode dependence = JacksonUtils.createObjectNode(); 13 | protected ObjectNode conditionResult; 14 | protected ObjectNode waitStartTimeout = JacksonUtils.createObjectNode(); 15 | protected ObjectNode switchResult = JacksonUtils.createObjectNode(); 16 | 17 | public abstract String getTaskType(); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/remote/TypeReferenceHttpResult.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.remote; 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference; 4 | import com.github.weaksloth.dolphins.util.JacksonUtils; 5 | import java.lang.reflect.Type; 6 | 7 | public class TypeReferenceHttpResult extends TypeReference> { 8 | 9 | protected final Type type; 10 | 11 | public TypeReferenceHttpResult(Class... clazz) { 12 | type = 13 | JacksonUtils.getObjectMapper() 14 | .getTypeFactory() 15 | .constructParametricType(HttpRestResult.class, clazz); 16 | } 17 | 18 | @Override 19 | public Type getType() { 20 | return type; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/Priority.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** define process and task priority */ 4 | public enum Priority { 5 | 6 | /** 0 highest priority 1 higher priority 2 medium priority 3 lower priority 4 lowest priority */ 7 | HIGHEST(0, "highest"), 8 | HIGH(1, "high"), 9 | MEDIUM(2, "medium"), 10 | LOW(3, "low"), 11 | LOWEST(4, "lowest"); 12 | 13 | Priority(int code, String descp) { 14 | this.code = code; 15 | this.descp = descp; 16 | } 17 | 18 | private final int code; 19 | private final String descp; 20 | 21 | public int getCode() { 22 | return code; 23 | } 24 | 25 | public String getDescp() { 26 | return descp; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Example user template template 3 | ### Example user template 4 | 5 | # IntelliJ project files 6 | .idea 7 | *.iml 8 | out 9 | gen 10 | # eclipse project files 11 | .project 12 | .settings 13 | */.settings/ 14 | */.classpath 15 | 16 | ### Java template 17 | # Compiled class file 18 | *.class 19 | 20 | # Log file 21 | *.log 22 | 23 | # BlueJ files 24 | *.ctxt 25 | 26 | # Mobile Tools for Java (J2ME) 27 | .mtj.tmp/ 28 | 29 | # Package Files # 30 | *.jar 31 | !**/test/resources/*.jar 32 | *.war 33 | *.nar 34 | *.ear 35 | *.zip 36 | *.tar.gz 37 | *.rar 38 | 39 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 40 | hs_err_pid* 41 | 42 | .idea/ 43 | **/target -------------------------------------------------------------------------------- /src/test/java/com/github/weaksloth/dolphins/utils/TaskLocationUtilsTest.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.utils; 2 | 3 | import com.github.weaksloth.dolphins.process.TaskLocation; 4 | import com.github.weaksloth.dolphins.util.TaskLocationUtils; 5 | import java.util.List; 6 | import org.junit.Test; 7 | 8 | public class TaskLocationUtilsTest { 9 | 10 | @Test 11 | public void testHorizontalLocation() { 12 | List taskLocations = TaskLocationUtils.horizontalLocation(1L, 2L, 3L, 4L); 13 | System.out.println(taskLocations); 14 | } 15 | 16 | @Test 17 | public void testVerticalLocation() { 18 | List taskLocations = TaskLocationUtils.verticalLocation(1L, 2L, 3L, 4L); 19 | System.out.println(taskLocations); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/resource/ResourceCreateParam.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.resource; 2 | 3 | import com.github.weaksloth.dolphins.core.DolphinClientConstant; 4 | import lombok.Data; 5 | import lombok.experimental.Accessors; 6 | 7 | /** create resource param */ 8 | @Data 9 | @Accessors(chain = true) 10 | public class ResourceCreateParam { 11 | 12 | private String type = DolphinClientConstant.Resource.TYPE_FILE; 13 | 14 | private String pid = DolphinClientConstant.Resource.DEFAULT_PID_FILE; 15 | 16 | private String currentDir = DolphinClientConstant.Resource.DEFAULT_CURRENT_DIR; 17 | 18 | private String fileName; 19 | 20 | private String suffix; 21 | 22 | private String description; 23 | 24 | private String content; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/TaskDependType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** task node depend type */ 4 | public enum TaskDependType { 5 | 6 | /** 7 | * 0 run current tasks only 1 run current tasks and previous tasks 2 run current tasks and the 8 | * other tasks that depend on current tasks; 9 | */ 10 | TASK_ONLY(0, "task only"), 11 | TASK_PRE(1, "task pre"), 12 | TASK_POST(2, "task post"); 13 | 14 | TaskDependType(int code, String descp) { 15 | this.code = code; 16 | this.descp = descp; 17 | } 18 | 19 | private final int code; 20 | private final String descp; 21 | 22 | public int getCode() { 23 | return code; 24 | } 25 | 26 | public String getDescp() { 27 | return descp; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/AlertStatus.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** alert sending(execution) status */ 4 | public enum AlertStatus { 5 | 6 | /** 0 waiting executed; 1 execute successfully,2 execute failed */ 7 | WAIT_EXECUTION(0, "waiting executed"), 8 | EXECUTION_SUCCESS(1, "execute successfully"), 9 | EXECUTION_FAILURE(2, "execute failed"), 10 | EXECUTION_PARTIAL_SUCCESS(3, "execute partial successfully"); 11 | 12 | AlertStatus(int code, String descp) { 13 | this.code = code; 14 | this.descp = descp; 15 | } 16 | 17 | private final int code; 18 | private final String descp; 19 | 20 | public int getCode() { 21 | return code; 22 | } 23 | 24 | public String getDescp() { 25 | return descp; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/UdfType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | /** UDF type */ 4 | public enum UdfType { 5 | 6 | /** 0 hive; 1 spark */ 7 | HIVE(0, "hive"), 8 | SPARK(1, "spark"); 9 | 10 | UdfType(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 int getCode() { 19 | return code; 20 | } 21 | 22 | public String getDescp() { 23 | return descp; 24 | } 25 | 26 | public static UdfType of(int type) { 27 | for (UdfType ut : values()) { 28 | if (ut.getCode() == type) { 29 | return ut; 30 | } 31 | } 32 | throw new IllegalArgumentException("invalid type : " + type); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/task/ShellTask.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 | @EqualsAndHashCode(callSuper = true) 11 | @Data 12 | @Accessors(chain = true) 13 | public class ShellTask extends AbstractTask { 14 | 15 | /** resource list */ 16 | private List resourceList = Collections.emptyList(); 17 | 18 | private List localParams = Collections.emptyList(); 19 | 20 | /** shell script */ 21 | private String rawScript; 22 | 23 | @Override 24 | public String getTaskType() { 25 | return "SHELL"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/datasource/DataSourceUpdateParam.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 | /** update datasource param */ 8 | @Data 9 | @Accessors(chain = true) 10 | public class DataSourceUpdateParam { 11 | 12 | /** datasource id */ 13 | private Long id; 14 | 15 | private String database; 16 | 17 | private String host; 18 | 19 | private String name; 20 | 21 | private String userName; 22 | 23 | private String password; 24 | 25 | private String type; 26 | 27 | private String port; 28 | 29 | private String note; 30 | 31 | /** jdbc connect params, json example: {"useServerPrepStmts":"true","useSSL":"false"} */ 32 | private Map other; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/enums/StateEventType.java: -------------------------------------------------------------------------------- 1 | package com.github.weaksloth.dolphins.enums; 2 | 3 | public enum StateEventType { 4 | PROCESS_STATE_CHANGE(0, "process state change"), 5 | TASK_STATE_CHANGE(1, "task state change"), 6 | PROCESS_TIMEOUT(2, "process timeout"), 7 | TASK_TIMEOUT(3, "task timeout"), 8 | WAKE_UP_TASK_GROUP(4, "wait task group"), 9 | TASK_RETRY(5, "task retry"), 10 | PROCESS_BLOCKED(6, "process blocked"), 11 | PROCESS_SUBMIT_FAILED(7, "process submit failed"); 12 | 13 | StateEventType(int code, String descp) { 14 | this.code = code; 15 | this.descp = descp; 16 | } 17 | 18 | private final int code; 19 | private final String descp; 20 | 21 | public int getCode() { 22 | return code; 23 | } 24 | 25 | public String getDescp() { 26 | return descp; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/github/weaksloth/dolphins/task/ProcedureTask.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.experimental.Accessors; 8 | 9 | @Data 10 | @Accessors(chain = true) 11 | public class ProcedureTask extends AbstractTask { 12 | 13 | /** datasource type */ 14 | private String type; 15 | 16 | /** datasource id */ 17 | private Integer datasource; 18 | 19 | private String method; 20 | 21 | /** resource list */ 22 | private List resourceList = Collections.emptyList(); 23 | 24 | private List 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 | --------------------------------------------------------------------------------