trigger
This commit is contained in:
parent
525a446bd6
commit
e4212340aa
|
|
@ -77,6 +77,11 @@
|
|||
<artifactId>dolphinscheduler-task-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-trigger-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-ui</artifactId>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.apache.dolphinscheduler.plugin.datasource.api.plugin.DataSourceProces
|
|||
import org.apache.dolphinscheduler.plugin.storage.api.StorageConfiguration;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskChannelFactory;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerPluginManager;
|
||||
import org.apache.dolphinscheduler.registry.api.RegistryConfiguration;
|
||||
import org.apache.dolphinscheduler.service.ServiceConfiguration;
|
||||
import org.apache.dolphinscheduler.spi.params.PluginParamsTransfer;
|
||||
|
|
@ -70,6 +71,7 @@ public class ApiApplicationServer {
|
|||
log.info("Received spring application context ready event will load taskPlugin and write to DB");
|
||||
// install task plugin
|
||||
TaskPluginManager.loadPlugin();
|
||||
TriggerPluginManager.loadPlugin();
|
||||
DataSourceProcessorProvider.initialize();
|
||||
for (Map.Entry<String, TaskChannelFactory> entry : TaskPluginManager.getTaskChannelFactoryMap().entrySet()) {
|
||||
String taskPluginName = entry.getKey();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.api.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dolphinscheduler.api.audit.OperatorLog;
|
||||
import org.apache.dolphinscheduler.api.audit.enums.AuditType;
|
||||
import org.apache.dolphinscheduler.api.exceptions.ApiException;
|
||||
import org.apache.dolphinscheduler.api.service.ExecutorService;
|
||||
import org.apache.dolphinscheduler.api.service.TriggerDefinitionService;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.constants.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.*;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.*;
|
||||
|
||||
/**
|
||||
* trigger definition controller
|
||||
*/
|
||||
@Tag(name = "TRIGGER_DEFINITION_TAG")
|
||||
@RestController
|
||||
@RequestMapping("projects/{projectCode}/trigger-definition")
|
||||
@Slf4j
|
||||
public class TriggerController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private ExecutorService execService;
|
||||
|
||||
@Autowired
|
||||
private TriggerDefinitionService triggerDefinitionService;
|
||||
|
||||
/**
|
||||
* create trigger definition
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @param projectCode project code
|
||||
* @param triggerDefinitionJson trigger definition json
|
||||
* @return create result code
|
||||
*/
|
||||
@Operation(summary = "save", description = "CREATE_TRIGGER_DEFINITION_NOTES")
|
||||
@Parameters({
|
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true, schema = @Schema(implementation = long.class)),
|
||||
@Parameter(name = "triggerDefinitionJson", description = "TRIGGER_DEFINITION_JSON", required = true, schema = @Schema(implementation = String.class))
|
||||
})
|
||||
@PostMapping()
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
// change error code
|
||||
@ApiException(CREATE_TASK_DEFINITION_ERROR)
|
||||
// change audit type
|
||||
@OperatorLog(auditType = AuditType.TASK_CREATE)
|
||||
public Result createTriggerDefinition(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
|
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
|
||||
@RequestParam(value = "triggerDefinitionJson", required = true) String triggerDefinitionJson) {
|
||||
Map<String, Object> result =
|
||||
triggerDefinitionService.createTriggerDefinition(loginUser, projectCode, triggerDefinitionJson);
|
||||
return returnDataList(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* query task definition list paging
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @param projectCode project code
|
||||
* @param searchTriggerName searchTaskName
|
||||
* @param triggerType taskType
|
||||
* @param pageNo page number
|
||||
* @param pageSize page size
|
||||
* @return task definition page
|
||||
*/
|
||||
@Operation(summary = "queryTaskDefinitionListPaging", description = "QUERY_TASK_DEFINITION_LIST_PAGING_NOTES")
|
||||
@Parameters({
|
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = false, schema = @Schema(implementation = long.class)),
|
||||
@Parameter(name = "searchWorkflowName", description = "SEARCH_WORKFLOW_NAME", required = false, schema = @Schema(implementation = String.class)),
|
||||
@Parameter(name = "searchTaskName", description = "SEARCH_TASK_NAME", required = false, schema = @Schema(implementation = String.class)),
|
||||
@Parameter(name = "taskType", description = "TASK_TYPE", required = false, schema = @Schema(implementation = String.class, example = "SHELL")),
|
||||
@Parameter(name = "taskExecuteType", description = "TASK_EXECUTE_TYPE", required = false, schema = @Schema(implementation = TaskExecuteType.class, example = "STREAM")),
|
||||
@Parameter(name = "pageNo", description = "PAGE_NO", required = true, schema = @Schema(implementation = int.class, example = "1")),
|
||||
@Parameter(name = "pageSize", description = "PAGE_SIZE", required = true, schema = @Schema(implementation = int.class, example = "10"))
|
||||
})
|
||||
@GetMapping()
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ApiException(QUERY_TASK_DEFINITION_LIST_PAGING_ERROR)
|
||||
public Result queryTaskDefinitionListPaging(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
|
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode,
|
||||
@RequestParam(value = "searchTriggerName", required = false) String searchTriggerName,
|
||||
@RequestParam(value = "triggerType", required = false) String triggerType,
|
||||
@RequestParam("pageNo") Integer pageNo,
|
||||
@RequestParam("pageSize") Integer pageSize) {
|
||||
checkPageParams(pageNo, pageSize);
|
||||
searchTriggerName = ParameterUtils.handleEscapes(searchTriggerName);
|
||||
return triggerDefinitionService.queryTriggerDefinitionListPaging(loginUser, projectCode,
|
||||
searchTriggerName, triggerType, pageNo, pageSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.apache.dolphinscheduler.api.service;
|
||||
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.enums.TaskExecuteType;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* trigger definition service
|
||||
*/
|
||||
public interface TriggerDefinitionService {
|
||||
|
||||
Map<String, Object> createTriggerDefinition(User loginUser,
|
||||
long projectCode,
|
||||
String triggerDefinitionJson);
|
||||
|
||||
Result queryTriggerDefinitionListPaging(User loginUser,
|
||||
long projectCode,
|
||||
String searchTriggerName,
|
||||
String triggerType,
|
||||
Integer pageNo,
|
||||
Integer pageSize);
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.api.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.dolphinscheduler.api.dto.task.TaskCreateRequest;
|
||||
import org.apache.dolphinscheduler.api.dto.task.TaskFilterRequest;
|
||||
import org.apache.dolphinscheduler.api.dto.task.TaskUpdateRequest;
|
||||
import org.apache.dolphinscheduler.api.dto.taskRelation.TaskRelationUpdateUpstreamRequest;
|
||||
import org.apache.dolphinscheduler.api.dto.workflow.WorkflowUpdateRequest;
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException;
|
||||
import org.apache.dolphinscheduler.api.permission.PermissionCheck;
|
||||
import org.apache.dolphinscheduler.api.service.*;
|
||||
import org.apache.dolphinscheduler.api.utils.PageInfo;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.api.vo.TaskDefinitionVO;
|
||||
import org.apache.dolphinscheduler.common.constants.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.*;
|
||||
import org.apache.dolphinscheduler.common.utils.CodeGenerateUtils;
|
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils;
|
||||
import org.apache.dolphinscheduler.dao.entity.*;
|
||||
import org.apache.dolphinscheduler.dao.mapper.*;
|
||||
import org.apache.dolphinscheduler.dao.repository.ProcessTaskRelationLogDao;
|
||||
import org.apache.dolphinscheduler.dao.repository.TaskDefinitionDao;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parameters.ParametersNode;
|
||||
import org.apache.dolphinscheduler.service.process.ProcessService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.*;
|
||||
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TASK_DEFINITION;
|
||||
|
||||
/**
|
||||
* tenant service impl
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class TriggerDefinitionServiceImpl extends BaseServiceImpl implements TriggerDefinitionService {
|
||||
|
||||
@Autowired
|
||||
private ProjectMapper projectMapper;
|
||||
|
||||
@Autowired
|
||||
private ProjectService projectService;
|
||||
|
||||
@Autowired
|
||||
private TaskDefinitionMapper taskDefinitionMapper;
|
||||
|
||||
@Autowired
|
||||
private TriggerDefinitionMapper triggerDefinitionMapper;
|
||||
|
||||
@Autowired
|
||||
private TaskDefinitionDao taskDefinitionDao;
|
||||
|
||||
@Autowired
|
||||
private TaskDefinitionLogMapper taskDefinitionLogMapper;
|
||||
|
||||
@Autowired
|
||||
private ProcessTaskRelationMapper processTaskRelationMapper;
|
||||
|
||||
@Autowired
|
||||
private ProcessTaskRelationLogDao processTaskRelationLogDao;
|
||||
|
||||
@Autowired
|
||||
private ProcessTaskRelationService processTaskRelationService;
|
||||
|
||||
@Autowired
|
||||
private ProcessDefinitionMapper processDefinitionMapper;
|
||||
|
||||
@Autowired
|
||||
private ProcessService processService;
|
||||
|
||||
@Autowired
|
||||
private ProcessDefinitionService processDefinitionService;
|
||||
|
||||
@Autowired
|
||||
private ProcessDefinitionLogMapper processDefinitionLogMapper;
|
||||
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Map<String, Object> createTriggerDefinition(User loginUser,
|
||||
long projectCode,
|
||||
String triggerDefinitionJson) {
|
||||
Project project = projectMapper.queryByCode(projectCode);
|
||||
// check if user have write perm for project
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result queryTriggerDefinitionListPaging(User loginUser,
|
||||
long projectCode,
|
||||
String searchTriggerName,
|
||||
String triggerType,
|
||||
Integer pageNo,
|
||||
Integer pageSize) {
|
||||
Result result = new Result();
|
||||
Project project = projectMapper.queryByCode(projectCode);
|
||||
// check user access for project
|
||||
Map<String, Object> checkResult =
|
||||
projectService.checkProjectAndAuth(loginUser, project, projectCode, TASK_DEFINITION);
|
||||
Status resultStatus = (Status) checkResult.get(Constants.STATUS);
|
||||
if (resultStatus != Status.SUCCESS) {
|
||||
putMsg(result, resultStatus);
|
||||
return result;
|
||||
}
|
||||
triggerType = triggerType == null ? StringUtils.EMPTY : triggerType;
|
||||
Page<TriggerMainInfo> page = new Page<>(pageNo, pageSize);
|
||||
// first, query trigger code by page size
|
||||
IPage<TriggerMainInfo> taskMainInfoIPage = triggerDefinitionMapper.queryDefinitionListPaging(page, projectCode,
|
||||
searchTriggerName, triggerType);
|
||||
PageInfo<TaskMainInfo> pageInfo = new PageInfo<>(pageNo, pageSize);
|
||||
pageInfo.setTotal((int) taskMainInfoIPage.getTotal());
|
||||
// pageInfo.setTotalList(taskMainInfoIPage.getRecords());
|
||||
result.setData(pageInfo);
|
||||
putMsg(result, Status.SUCCESS);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.dao.entity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@Data
|
||||
@TableName("t_ds_trigger_definition")
|
||||
public class TriggerDefinition {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* code
|
||||
*/
|
||||
private long code;
|
||||
|
||||
/**
|
||||
* name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* description
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* project code
|
||||
*/
|
||||
private long projectCode;
|
||||
|
||||
/**
|
||||
* trigger user id
|
||||
*/
|
||||
private int userId;
|
||||
|
||||
/**
|
||||
* trigger type
|
||||
*/
|
||||
private String triggerType;
|
||||
|
||||
/**
|
||||
* create time
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* update time
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
public TriggerDefinition() {
|
||||
}
|
||||
|
||||
public TriggerDefinition(long code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
TriggerDefinition that = (TriggerDefinition) o;
|
||||
return Objects.equals(name, that.name)
|
||||
&& Objects.equals(description, that.description);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.dao.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import lombok.Data;
|
||||
|
||||
import org.apache.dolphinscheduler.common.constants.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.Flag;
|
||||
import org.apache.dolphinscheduler.common.enums.Priority;
|
||||
import org.apache.dolphinscheduler.common.enums.TaskExecuteType;
|
||||
import org.apache.dolphinscheduler.common.utils.DateUtils;
|
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parameters.DependentParameters;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parameters.SwitchParameters;
|
||||
|
||||
import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.*;
|
||||
import static org.apache.dolphinscheduler.plugin.task.api.TaskConstants.TASK_TYPE_BLOCKING;
|
||||
|
||||
@Data
|
||||
@TableName("t_ds_trigger_instance")
|
||||
public class TriggerInstance implements Serializable {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* task name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* task type
|
||||
*/
|
||||
private String triggerType;
|
||||
|
||||
private int processInstanceId;
|
||||
|
||||
private String processInstanceName;
|
||||
|
||||
private Long projectCode;
|
||||
|
||||
private long triggerCode;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String processDefinitionName;
|
||||
|
||||
/**
|
||||
* state
|
||||
*/
|
||||
private TaskExecutionStatus state;
|
||||
|
||||
/**
|
||||
* task first submit time.
|
||||
*/
|
||||
private Date firstSubmitTime;
|
||||
|
||||
/**
|
||||
* task submit time
|
||||
*/
|
||||
private Date submitTime;
|
||||
|
||||
/**
|
||||
* task start time
|
||||
*/
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* task end time
|
||||
*/
|
||||
private Date endTime;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.dao.entity;
|
||||
|
||||
import org.apache.dolphinscheduler.common.enums.ReleaseState;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* task main info
|
||||
*/
|
||||
@Data
|
||||
public class TriggerMainInfo {
|
||||
private long id;
|
||||
|
||||
/**
|
||||
* task name
|
||||
*/
|
||||
private String taskName;
|
||||
|
||||
/**
|
||||
* task code
|
||||
*/
|
||||
private long taskCode;
|
||||
|
||||
/**
|
||||
* task version
|
||||
*/
|
||||
private int taskVersion;
|
||||
|
||||
/**
|
||||
* task type
|
||||
*/
|
||||
private String taskType;
|
||||
|
||||
/**
|
||||
* create time
|
||||
*/
|
||||
private Date taskCreateTime;
|
||||
|
||||
/**
|
||||
* update time
|
||||
*/
|
||||
private Date taskUpdateTime;
|
||||
|
||||
/**
|
||||
* projectCode
|
||||
*/
|
||||
private long projectCode;
|
||||
|
||||
/**
|
||||
* processDefinitionCode
|
||||
*/
|
||||
private long processDefinitionCode;
|
||||
|
||||
/**
|
||||
* processDefinitionVersion
|
||||
*/
|
||||
private int processDefinitionVersion;
|
||||
|
||||
/**
|
||||
* processDefinitionName
|
||||
*/
|
||||
private String processDefinitionName;
|
||||
|
||||
/**
|
||||
* processReleaseState
|
||||
*/
|
||||
private ReleaseState processReleaseState;
|
||||
|
||||
/**
|
||||
* upstreamTaskMap(k:code,v:name)
|
||||
*/
|
||||
private Map<Long, String> upstreamTaskMap;
|
||||
|
||||
/**
|
||||
* upstreamTaskCode
|
||||
*/
|
||||
private long upstreamTaskCode;
|
||||
|
||||
/**
|
||||
* upstreamTaskName
|
||||
*/
|
||||
private String upstreamTaskName;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package org.apache.dolphinscheduler.dao.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@Data
|
||||
@TableName("t_ds_trigger_offset")
|
||||
public class TriggerOffset {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* code
|
||||
*/
|
||||
private long code;
|
||||
|
||||
public TriggerOffset() {
|
||||
}
|
||||
|
||||
public TriggerOffset(long code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.dao.mapper;
|
||||
|
||||
import org.apache.dolphinscheduler.common.enums.TaskExecuteType;
|
||||
import org.apache.dolphinscheduler.dao.entity.*;
|
||||
import org.apache.dolphinscheduler.dao.model.WorkflowDefinitionCountDto;
|
||||
|
||||
import org.apache.ibatis.annotations.MapKey;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
||||
/**
|
||||
* trigger definition mapper interface
|
||||
*/
|
||||
|
||||
public interface TriggerDefinitionMapper extends BaseMapper<TriggerDefinition> {
|
||||
|
||||
/**
|
||||
* query trigger definition by name
|
||||
*
|
||||
* @param projectCode projectCode
|
||||
* @param processCode processCode
|
||||
* @param name name
|
||||
* @return trigger definition
|
||||
*/
|
||||
TriggerDefinition queryByName(@Param("projectCode") long projectCode,
|
||||
@Param("processCode") long processCode,
|
||||
@Param("name") String name);
|
||||
|
||||
/**
|
||||
* query trigger definition by code
|
||||
*
|
||||
* @param code taskDefinitionCode
|
||||
* @return trigger definition
|
||||
*/
|
||||
TriggerDefinition queryByCode(@Param("code") long code);
|
||||
|
||||
/**
|
||||
* query all trigger definition list
|
||||
*
|
||||
* @param projectCode projectCode
|
||||
* @return trigger definition list
|
||||
*/
|
||||
List<TriggerDefinition> queryAllDefinitionList(@Param("projectCode") long projectCode);
|
||||
|
||||
/**
|
||||
* task main info page
|
||||
*
|
||||
* @param page page
|
||||
* @param projectCode projectCode
|
||||
* @param searchTriggerName searchTriggerName
|
||||
* @param triggerType triggerType
|
||||
* @return task main info IPage
|
||||
*/
|
||||
IPage<TriggerMainInfo> queryDefinitionListPaging(IPage<TriggerMainInfo> page,
|
||||
@Param("projectCode") long projectCode,
|
||||
@Param("searchTaskName") String searchTriggerName,
|
||||
@Param("taskType") String triggerType);
|
||||
|
||||
/**
|
||||
* delete trigger definition by code
|
||||
*
|
||||
* @param code code
|
||||
* @return int
|
||||
*/
|
||||
int deleteByCode(@Param("code") long code);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.apache.dolphinscheduler.dao.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.apache.dolphinscheduler.common.enums.TaskExecuteType;
|
||||
import org.apache.dolphinscheduler.dao.entity.*;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public interface TriggerInstanceMapper extends BaseMapper<TriggerInstance> {
|
||||
|
||||
/**
|
||||
* query trigger definition by code
|
||||
*
|
||||
* @param code taskDefinitionCode
|
||||
* @return trigger definition
|
||||
*/
|
||||
TriggerInstance queryByCode(@Param("code") long code);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package org.apache.dolphinscheduler.dao.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.dolphinscheduler.dao.entity.*;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface TriggerOffsetMapper extends BaseMapper<TriggerOffset> {
|
||||
|
||||
/**
|
||||
* query trigger definition by code
|
||||
*
|
||||
* @param code taskDefinitionCode
|
||||
* @return trigger definition
|
||||
*/
|
||||
TriggerOffset queryByCode(@Param("code") long code);
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.dao.repository;
|
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.TriggerDefinition;
|
||||
|
||||
/**
|
||||
* Trigger Definition DAO
|
||||
*/
|
||||
public interface TriggerDefinitionDao extends IDao<TriggerDefinition> {
|
||||
TriggerDefinition queryByCode(long triggerCode);
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package org.apache.dolphinscheduler.dao.repository;
|
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.TriggerInstance;
|
||||
|
||||
/**
|
||||
* Trigger Instance DAO
|
||||
*/
|
||||
public interface TriggerInstanceDao extends IDao<TriggerInstance> {
|
||||
TriggerInstance queryByCode(long triggerCode);
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.dao.repository.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dolphinscheduler.dao.entity.*;
|
||||
import org.apache.dolphinscheduler.dao.mapper.*;
|
||||
import org.apache.dolphinscheduler.dao.repository.BaseDao;
|
||||
import org.apache.dolphinscheduler.dao.repository.TriggerDefinitionDao;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@Slf4j
|
||||
public class TriggerDefinitionDaoImpl extends BaseDao<TriggerDefinition, TriggerDefinitionMapper> implements TriggerDefinitionDao {
|
||||
|
||||
@Autowired
|
||||
private ProcessDefinitionMapper processDefinitionMapper;
|
||||
|
||||
@Autowired
|
||||
private ProcessTaskRelationLogMapper processTaskRelationLogMapper;
|
||||
|
||||
@Autowired
|
||||
private TaskDefinitionLogMapper taskDefinitionLogMapper;
|
||||
|
||||
public TriggerDefinitionDaoImpl(@NonNull TriggerDefinitionMapper triggerDefinitionMapper) {
|
||||
super(triggerDefinitionMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TriggerDefinition queryByCode(long triggerCode) {
|
||||
return mybatisMapper.queryByCode(triggerCode);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.dao.repository.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dolphinscheduler.dao.entity.*;
|
||||
import org.apache.dolphinscheduler.dao.mapper.*;
|
||||
import org.apache.dolphinscheduler.dao.repository.BaseDao;
|
||||
import org.apache.dolphinscheduler.dao.repository.TriggerInstanceDao;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@Slf4j
|
||||
public class TriggerInstanceDaoImpl extends BaseDao<TriggerInstance, TriggerInstanceMapper> implements TriggerInstanceDao {
|
||||
|
||||
@Autowired
|
||||
private ProcessDefinitionMapper processDefinitionMapper;
|
||||
|
||||
@Autowired
|
||||
private ProcessTaskRelationLogMapper processTaskRelationLogMapper;
|
||||
|
||||
@Autowired
|
||||
private TaskDefinitionLogMapper taskDefinitionLogMapper;
|
||||
|
||||
public TriggerInstanceDaoImpl(@NonNull TriggerInstanceMapper triggerInstanceMapper) {
|
||||
super(triggerInstanceMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TriggerInstance queryByCode(long triggerCode) {
|
||||
return mybatisMapper.queryByCode(triggerCode);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="org.apache.dolphinscheduler.dao.mapper.TriggerDefinitionMapper">
|
||||
<select id="queryDefinitionListPaging" resultType="org.apache.dolphinscheduler.dao.entity.TriggerMainInfo">
|
||||
select td.code task_code
|
||||
from t_ds_trigger_definition td
|
||||
WHERE td.project_code = #{projectCode}
|
||||
<if test="triggerType != ''">
|
||||
and td.trigger_type = #{taskType}
|
||||
</if>
|
||||
<if test="searchTriggerName != null and searchTriggerName != ''">
|
||||
and td.name like concat('%', #{searchTriggerName}, '%')
|
||||
</if>
|
||||
order by td.update_time desc
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -499,6 +499,57 @@ CREATE TABLE t_ds_task_definition
|
|||
PRIMARY KEY (id, code)
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_trigger_offset
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS t_ds_trigger_offset CASCADE;
|
||||
CREATE TABLE t_ds_trigger_offset
|
||||
(
|
||||
id int(11) NOT NULL,
|
||||
code bigint(20) NOT NULL,
|
||||
PRIMARY KEY (id, code)
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_trigger_definition
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS t_ds_trigger_definition CASCADE;
|
||||
CREATE TABLE t_ds_trigger_definition
|
||||
(
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
code bigint(20) NOT NULL,
|
||||
name varchar(255) DEFAULT NULL,
|
||||
description text,
|
||||
project_code bigint(20) NOT NULL,
|
||||
user_id int(11) DEFAULT NULL,
|
||||
trigger_type varchar(50) NOT NULL,
|
||||
trigger_params longtext,
|
||||
create_time datetime NOT NULL,
|
||||
update_time datetime DEFAULT NULL,
|
||||
PRIMARY KEY (id, code)
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_trigger_instance
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS t_ds_trigger_instance CASCADE;
|
||||
CREATE TABLE t_ds_trigger_instance
|
||||
(
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255) DEFAULT NULL,
|
||||
trigger_type varchar(50) NOT NULL,
|
||||
trigger_code bigint(20) NOT NULL,
|
||||
process_instance_id int(11) DEFAULT NULL,
|
||||
process_instance_name varchar(255) DEFAULT NULL,
|
||||
project_code bigint(20) DEFAULT NULL,
|
||||
state tinyint(4) DEFAULT NULL,
|
||||
submit_time datetime DEFAULT NULL,
|
||||
start_time datetime DEFAULT NULL,
|
||||
end_time datetime DEFAULT NULL,
|
||||
trigger_params longtext,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_task_definition_log
|
||||
-- ----------------------------
|
||||
|
|
@ -2154,7 +2205,6 @@ CREATE TABLE t_ds_trigger_relation
|
|||
UNIQUE KEY t_ds_trigger_relation_UN(trigger_type,job_id,trigger_code)
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS t_ds_relation_sub_workflow;
|
||||
CREATE TABLE t_ds_relation_sub_workflow (
|
||||
id BIGINT AUTO_INCREMENT NOT NULL,
|
||||
|
|
|
|||
|
|
@ -939,6 +939,68 @@ CREATE TABLE `t_ds_task_instance` (
|
|||
-- Records of t_ds_task_instance
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_trigger_offset
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `t_ds_trigger_offset`;
|
||||
CREATE TABLE `t_ds_trigger_offset` (
|
||||
`id` int(11) NOT NULL COMMENT 'self-increasing id',
|
||||
`code` bigint(20) NOT NULL COMMENT 'encoding',
|
||||
PRIMARY KEY (`id`,`code`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE = utf8_bin;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of t_ds_trigger_offset
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_trigger_definition
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `t_ds_trigger_definition`;
|
||||
CREATE TABLE `t_ds_trigger_definition` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'self-increasing id',
|
||||
`code` bigint(20) NOT NULL COMMENT 'encoding',
|
||||
`name` varchar(255) DEFAULT NULL COMMENT 'trigger definition name',
|
||||
`description` text COMMENT 'description',
|
||||
`project_code` bigint(20) NOT NULL COMMENT 'project code',
|
||||
`user_id` int(11) DEFAULT NULL COMMENT 'trigger definition creator id',
|
||||
`trigger_type` varchar(50) NOT NULL COMMENT 'trigger type',
|
||||
`trigger_params` longtext COMMENT 'job custom parameters',
|
||||
`create_time` datetime NOT NULL COMMENT 'create time',
|
||||
`update_time` datetime NOT NULL COMMENT 'update time',
|
||||
PRIMARY KEY (`id`,`code`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE = utf8_bin;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of t_ds_trigger_definition
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_trigger_instance
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `t_ds_trigger_instance`;
|
||||
CREATE TABLE `t_ds_trigger_instance` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'key',
|
||||
`name` varchar(255) DEFAULT NULL COMMENT 'trigger name',
|
||||
`trigger_type` varchar(50) NOT NULL COMMENT 'trigger type',
|
||||
`trigger_code` bigint(20) NOT NULL COMMENT 'trigger definition code',
|
||||
`process_instance_id` int(11) DEFAULT NULL COMMENT 'process instance id',
|
||||
`process_instance_name` varchar(255) DEFAULT NULL COMMENT 'process instance name',
|
||||
`project_code` bigint(20) DEFAULT NULL COMMENT 'project code',
|
||||
`state` tinyint(4) DEFAULT NULL COMMENT 'Status: 0 commit succeeded, 1 running, 2 prepare to pause, 3 pause, 4 prepare to stop, 5 stop, 6 fail, 7 succeed, 8 need fault tolerance, 9 kill, 10 wait for thread, 11 wait for dependency to complete',
|
||||
`submit_time` datetime DEFAULT NULL COMMENT 'trigger submit time',
|
||||
`start_time` datetime DEFAULT NULL COMMENT 'trigger start time',
|
||||
`end_time` datetime DEFAULT NULL COMMENT 'trigger end time',
|
||||
`trigger_params` longtext COMMENT 'job custom parameters',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `process_instance_id` (`process_instance_id`) USING BTREE,
|
||||
KEY `idx_code_version` (`task_code`, `task_definition_version`) USING BTREE,
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE = utf8_bin;
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of t_ds_trigger_instance
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_tenant
|
||||
-- ----------------------------
|
||||
|
|
|
|||
|
|
@ -419,6 +419,61 @@ CREATE TABLE t_ds_task_definition (
|
|||
|
||||
create index task_definition_index on t_ds_task_definition (project_code,id);
|
||||
|
||||
--
|
||||
-- Table structure for table t_ds_trigger_offset
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS t_ds_trigger_offset;
|
||||
CREATE TABLE t_ds_trigger_offset (
|
||||
id int NOT NULL ,
|
||||
code bigint NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ;
|
||||
|
||||
--
|
||||
-- Table structure for table t_ds_trigger_definition
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS t_ds_trigger_definition;
|
||||
CREATE TABLE t_ds_trigger_definition (
|
||||
id int NOT NULL ,
|
||||
code bigint NOT NULL,
|
||||
name varchar(255) DEFAULT NULL ,
|
||||
description text ,
|
||||
project_code bigint DEFAULT NULL ,
|
||||
user_id int DEFAULT NULL ,
|
||||
trigger_type varchar(50) DEFAULT NULL ,
|
||||
trigger_params text ,
|
||||
create_time timestamp DEFAULT NULL ,
|
||||
update_time timestamp DEFAULT NULL ,
|
||||
PRIMARY KEY (id)
|
||||
) ;
|
||||
|
||||
create index trigger_definition_index on t_ds_trigger_definition (project_code,id);
|
||||
|
||||
--
|
||||
-- Table structure for table t_ds_trigger_instance
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS t_ds_trigger_instance;
|
||||
CREATE TABLE t_ds_trigger_instance (
|
||||
id int NOT NULL ,
|
||||
name varchar(255) DEFAULT NULL ,
|
||||
trigger_type varchar(50) DEFAULT NULL ,
|
||||
trigger_code bigint NOT NULL,
|
||||
process_instance_id int DEFAULT NULL ,
|
||||
process_instance_name varchar(255) DEFAULT NULL,
|
||||
project_code bigint DEFAULT NULL,
|
||||
state int DEFAULT NULL ,
|
||||
submit_time timestamp DEFAULT NULL ,
|
||||
start_time timestamp DEFAULT NULL ,
|
||||
end_time timestamp DEFAULT NULL ,
|
||||
trigger_params text ,
|
||||
PRIMARY KEY (id)
|
||||
) ;
|
||||
|
||||
create index idx_trigger_instance_code_version on t_ds_trigger_instance (task_code, task_definition_version);
|
||||
|
||||
--
|
||||
-- Table structure for table t_ds_task_definition_log
|
||||
--
|
||||
|
|
@ -838,6 +893,8 @@ CREATE TABLE t_ds_task_instance (
|
|||
create index idx_task_instance_code_version on t_ds_task_instance (task_code, task_definition_version);
|
||||
create index idx_cache_key on t_ds_task_instance (cache_key);
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Table structure for table t_ds_tenant
|
||||
--
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dolphinscheduler.dao.mapper;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.dolphinscheduler.dao.BaseDaoTest;
|
||||
import org.apache.dolphinscheduler.dao.entity.TaskDefinition;
|
||||
import org.apache.dolphinscheduler.dao.entity.TriggerDefinition;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class TriggerDefinitionMapperTest extends BaseDaoTest {
|
||||
@Autowired
|
||||
private TriggerDefinitionMapper triggerDefinitionMapper;
|
||||
|
||||
public TriggerDefinition insertOne() {
|
||||
return insertOne(99);
|
||||
}
|
||||
|
||||
public TriggerDefinition insertOne(int userId) {
|
||||
TriggerDefinition triggerDefinition = new TriggerDefinition();
|
||||
triggerDefinition.setCode(888888L);
|
||||
triggerDefinition.setName("unit-test");
|
||||
triggerDefinition.setProjectCode(1L);
|
||||
triggerDefinition.setUserId(userId);
|
||||
triggerDefinition.setCreateTime(new Date());
|
||||
triggerDefinition.setUpdateTime(new Date());
|
||||
triggerDefinition.setTriggerType("unit-test");
|
||||
triggerDefinitionMapper.insert(triggerDefinition);
|
||||
return triggerDefinition;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsert() {
|
||||
TriggerDefinition triggerDefinition = insertOne();
|
||||
Assertions.assertNotEquals(0, triggerDefinition.getId().intValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.dao.mapper;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.dolphinscheduler.common.enums.WorkflowExecutionStatus;
|
||||
import org.apache.dolphinscheduler.dao.BaseDaoTest;
|
||||
import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
|
||||
import org.apache.dolphinscheduler.dao.entity.TriggerInstance;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class TriggerInstanceMapperTest extends BaseDaoTest {
|
||||
|
||||
@Autowired
|
||||
private ProcessDefinitionMapper processDefinitionMapper;
|
||||
|
||||
@Autowired
|
||||
private ProcessInstanceMapper processInstanceMapper;
|
||||
|
||||
@Autowired
|
||||
private TriggerInstanceMapper triggerInstanceMapper;
|
||||
|
||||
/**
|
||||
* insert
|
||||
*
|
||||
* @return ProcessInstance
|
||||
*/
|
||||
private ProcessInstance insertProcessInstance() {
|
||||
ProcessInstance processInstance = new ProcessInstance();
|
||||
processInstance.setId(1);
|
||||
processInstance.setName("taskName");
|
||||
processInstance.setState(WorkflowExecutionStatus.RUNNING_EXECUTION);
|
||||
processInstance.setStartTime(new Date());
|
||||
processInstance.setEndTime(new Date());
|
||||
processInstance.setProcessDefinitionCode(1L);
|
||||
processInstance.setProjectCode(1L);
|
||||
processInstance.setTestFlag(0);
|
||||
processInstanceMapper.insert(processInstance);
|
||||
return processInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* construct a task instance and then insert
|
||||
*/
|
||||
private TriggerInstance insertTriggerInstance(int processInstanceId) {
|
||||
TriggerInstance taskInstance = new TriggerInstance();
|
||||
taskInstance.setName("us task");
|
||||
taskInstance.setState(TaskExecutionStatus.RUNNING_EXECUTION);
|
||||
taskInstance.setStartTime(new Date());
|
||||
taskInstance.setEndTime(new Date());
|
||||
taskInstance.setTriggerType("asd");
|
||||
taskInstance.setProcessInstanceId(processInstanceId);
|
||||
taskInstance.setProjectCode(1L);
|
||||
triggerInstanceMapper.insert(taskInstance);
|
||||
return taskInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* test update
|
||||
*/
|
||||
@Test
|
||||
public void testUpdate() {
|
||||
// insert ProcessInstance
|
||||
ProcessInstance processInstance = insertProcessInstance();
|
||||
|
||||
// insert taskInstance
|
||||
TriggerInstance triggerInstance = insertTriggerInstance(processInstance.getId());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package org.apache.dolphinscheduler.dao.mapper;
|
||||
|
||||
import org.apache.dolphinscheduler.dao.BaseDaoTest;
|
||||
import org.apache.dolphinscheduler.dao.entity.TriggerOffset;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class TriggerOffsetMapperTest extends BaseDaoTest {
|
||||
@Autowired
|
||||
private TriggerOffsetMapper triggerOffsetMapper;
|
||||
|
||||
public TriggerOffset insertOne() {
|
||||
return insertOne(99);
|
||||
}
|
||||
|
||||
public TriggerOffset insertOne(int userId) {
|
||||
TriggerOffset triggerOffset = new TriggerOffset();
|
||||
triggerOffset.setId(1);
|
||||
triggerOffset.setCode(888888L);
|
||||
return triggerOffset;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsert() {
|
||||
TriggerOffset triggerDefinition = insertOne();
|
||||
Assertions.assertNotEquals(0, triggerDefinition.getId().intValue());
|
||||
}
|
||||
}
|
||||
|
|
@ -69,6 +69,11 @@
|
|||
<artifactId>dolphinscheduler-task-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-trigger-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-storage-all</artifactId>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.dolphinscheduler.meter.metrics.SystemMetrics;
|
|||
import org.apache.dolphinscheduler.plugin.datasource.api.plugin.DataSourceProcessorProvider;
|
||||
import org.apache.dolphinscheduler.plugin.storage.api.StorageConfiguration;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskPluginManager;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerPluginManager;
|
||||
import org.apache.dolphinscheduler.registry.api.RegistryConfiguration;
|
||||
import org.apache.dolphinscheduler.scheduler.api.SchedulerApi;
|
||||
import org.apache.dolphinscheduler.server.master.metrics.MasterServerMetrics;
|
||||
|
|
@ -38,6 +39,7 @@ import org.apache.dolphinscheduler.server.master.rpc.MasterRpcServer;
|
|||
import org.apache.dolphinscheduler.server.master.runner.EventExecuteService;
|
||||
import org.apache.dolphinscheduler.server.master.runner.FailoverExecuteThread;
|
||||
import org.apache.dolphinscheduler.server.master.runner.MasterSchedulerBootstrap;
|
||||
import org.apache.dolphinscheduler.server.master.runner.MasterTriggerBootstrap;
|
||||
import org.apache.dolphinscheduler.server.master.runner.taskgroup.TaskGroupCoordinator;
|
||||
import org.apache.dolphinscheduler.service.ServiceConfiguration;
|
||||
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
|
||||
|
|
@ -70,6 +72,9 @@ public class MasterServer implements IStoppable {
|
|||
@Autowired
|
||||
private MasterSchedulerBootstrap masterSchedulerBootstrap;
|
||||
|
||||
@Autowired
|
||||
private MasterTriggerBootstrap masterTriggerBootstrap;
|
||||
|
||||
@Autowired
|
||||
private SchedulerApi schedulerApi;
|
||||
|
||||
|
|
@ -109,6 +114,7 @@ public class MasterServer implements IStoppable {
|
|||
|
||||
// install task plugin
|
||||
TaskPluginManager.loadPlugin();
|
||||
TriggerPluginManager.loadPlugin();
|
||||
DataSourceProcessorProvider.initialize();
|
||||
|
||||
this.masterSlotManager.start();
|
||||
|
|
@ -119,6 +125,8 @@ public class MasterServer implements IStoppable {
|
|||
|
||||
this.masterSchedulerBootstrap.start();
|
||||
|
||||
this.masterTriggerBootstrap.start();
|
||||
|
||||
this.eventExecuteService.start();
|
||||
this.failoverExecuteThread.start();
|
||||
|
||||
|
|
@ -162,6 +170,7 @@ public class MasterServer implements IStoppable {
|
|||
try (
|
||||
SchedulerApi closedSchedulerApi = schedulerApi;
|
||||
MasterSchedulerBootstrap closedSchedulerBootstrap = masterSchedulerBootstrap;
|
||||
MasterTriggerBootstrap closedTriggerBootstrap = masterTriggerBootstrap;
|
||||
MasterRpcServer closedRpcServer = masterRPCServer;
|
||||
MasterRegistryClient closedMasterRegistryClient = masterRegistryClient;
|
||||
// close spring Context and will invoke method with @PreDestroy annotation to destroy beans.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
package org.apache.dolphinscheduler.server.master.runner;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.dolphinscheduler.common.constants.Constants;
|
||||
import org.apache.dolphinscheduler.common.lifecycle.ServerLifeCycleManager;
|
||||
import org.apache.dolphinscheduler.common.thread.BaseDaemonThread;
|
||||
import org.apache.dolphinscheduler.common.thread.ThreadUtils;
|
||||
import org.apache.dolphinscheduler.dao.entity.Command;
|
||||
import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
|
||||
import org.apache.dolphinscheduler.meter.metrics.MetricsProvider;
|
||||
import org.apache.dolphinscheduler.meter.metrics.SystemMetrics;
|
||||
import org.apache.dolphinscheduler.server.master.cache.ProcessInstanceExecCacheManager;
|
||||
import org.apache.dolphinscheduler.server.master.command.ICommandFetcher;
|
||||
import org.apache.dolphinscheduler.server.master.config.MasterConfig;
|
||||
import org.apache.dolphinscheduler.server.master.config.MasterServerLoadProtection;
|
||||
import org.apache.dolphinscheduler.server.master.event.WorkflowEvent;
|
||||
import org.apache.dolphinscheduler.server.master.event.WorkflowEventQueue;
|
||||
import org.apache.dolphinscheduler.server.master.event.WorkflowEventType;
|
||||
import org.apache.dolphinscheduler.server.master.exception.WorkflowCreateException;
|
||||
import org.apache.dolphinscheduler.server.master.metrics.MasterServerMetrics;
|
||||
import org.apache.dolphinscheduler.service.command.CommandService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class MasterTriggerBootstrap extends BaseDaemonThread implements AutoCloseable {
|
||||
|
||||
@Autowired
|
||||
private ICommandFetcher commandFetcher;
|
||||
|
||||
@Autowired
|
||||
private CommandService commandService;
|
||||
|
||||
@Autowired
|
||||
private MasterConfig masterConfig;
|
||||
|
||||
@Autowired
|
||||
private ProcessInstanceExecCacheManager processInstanceExecCacheManager;
|
||||
|
||||
@Autowired
|
||||
private WorkflowExecuteRunnableFactory workflowExecuteRunnableFactory;
|
||||
|
||||
@Autowired
|
||||
private WorkflowEventQueue workflowEventQueue;
|
||||
|
||||
@Autowired
|
||||
private WorkflowEventLooper workflowEventLooper;
|
||||
|
||||
@Autowired
|
||||
private MasterTaskExecutorBootstrap masterTaskExecutorBootstrap;
|
||||
|
||||
@Autowired
|
||||
private MetricsProvider metricsProvider;
|
||||
|
||||
protected MasterTriggerBootstrap() {
|
||||
super("MasterTriggerBootstrap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void start() {
|
||||
log.info("MasterTriggerBootstrap starting..");
|
||||
super.start();
|
||||
// workflowEventLooper.start();
|
||||
// masterTaskExecutorBootstrap.start();
|
||||
log.info("MasterTriggerBootstrap started...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
log.info("MasterTriggerBootstrap stopping...");
|
||||
// try (
|
||||
// final WorkflowEventLooper workflowEventLooper1 = workflowEventLooper;
|
||||
// final MasterTaskExecutorBootstrap masterTaskExecutorBootstrap1 = masterTaskExecutorBootstrap) {
|
||||
// // closed the resource
|
||||
// }
|
||||
log.info("MasterTriggerBootstrap stopped...");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
MasterServerLoadProtection serverLoadProtection = masterConfig.getServerLoadProtection();
|
||||
while (!ServerLifeCycleManager.isStopped()) {
|
||||
try {
|
||||
if (!ServerLifeCycleManager.isRunning()) {
|
||||
// the current server is not at running status, cannot consume command.
|
||||
log.warn("The current server is not at running status, cannot consumes commands.");
|
||||
Thread.sleep(Constants.SLEEP_TIME_MILLIS);
|
||||
}
|
||||
|
||||
// todo: if the workflow event queue is much, we need to handle the back pressure
|
||||
SystemMetrics systemMetrics = metricsProvider.getSystemMetrics();
|
||||
if (serverLoadProtection.isOverload(systemMetrics)) {
|
||||
log.warn("The current server is overload, cannot consumes commands.");
|
||||
MasterServerMetrics.incMasterOverload();
|
||||
Thread.sleep(Constants.SLEEP_TIME_MILLIS);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
List<Command> commands = commandFetcher.fetchCommands();
|
||||
if (CollectionUtils.isEmpty(commands)) {
|
||||
// indicate that no command ,sleep for 1s
|
||||
Thread.sleep(Constants.SLEEP_TIME_MILLIS);
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// commands.parallelStream()
|
||||
// .forEach(command -> {
|
||||
// try {
|
||||
// Optional<WorkflowExecuteRunnable> workflowExecuteRunnableOptional =
|
||||
// workflowExecuteRunnableFactory.createWorkflowExecuteRunnable(command);
|
||||
// if (!workflowExecuteRunnableOptional.isPresent()) {
|
||||
// log.warn(
|
||||
// "The command execute success, will not trigger a WorkflowExecuteRunnable, this workflowInstance might be in serial mode");
|
||||
// return;
|
||||
// }
|
||||
// WorkflowExecuteRunnable workflowExecuteRunnable = workflowExecuteRunnableOptional.get();
|
||||
// ProcessInstance processInstance = workflowExecuteRunnable
|
||||
// .getWorkflowExecuteContext().getWorkflowInstance();
|
||||
// if (processInstanceExecCacheManager.contains(processInstance.getId())) {
|
||||
// log.error(
|
||||
// "The workflow instance is already been cached, this case shouldn't be happened");
|
||||
// }
|
||||
// processInstanceExecCacheManager.cache(processInstance.getId(), workflowExecuteRunnable);
|
||||
// workflowEventQueue.addEvent(
|
||||
// new WorkflowEvent(WorkflowEventType.START_WORKFLOW, processInstance.getId()));
|
||||
// } catch (WorkflowCreateException workflowCreateException) {
|
||||
// log.error("Master handle command {} error ", command.getId(), workflowCreateException);
|
||||
// commandService.moveToErrorCommand(command, workflowCreateException.toString());
|
||||
// }
|
||||
// });
|
||||
// MasterServerMetrics.incMasterConsumeCommand(commands.size());
|
||||
} catch (InterruptedException interruptedException) {
|
||||
log.warn("MasterTriggerBootstrap interrupted, close the loop", interruptedException);
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
log.error("MasterTriggerBootstrap error", e);
|
||||
// sleep for 1s here to avoid the database down cause the exception boom
|
||||
ThreadUtils.sleep(Constants.SLEEP_TIME_MILLIS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
package org.apache.dolphinscheduler.server.master.runner;
|
||||
|
||||
import org.apache.dolphinscheduler.plugin.task.api.*;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.log.TaskInstanceLogHeader;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.utils.LogUtils;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerCallBack;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Slf4j
|
||||
public abstract class TriggerExecuteRunnable implements Runnable {
|
||||
|
||||
|
||||
protected @Nullable AbstractTask task;
|
||||
|
||||
protected TriggerExecuteRunnable() {
|
||||
}
|
||||
|
||||
protected void executeTrigger(TriggerCallBack triggerCallBack) {
|
||||
if (task == null) {
|
||||
throw new IllegalArgumentException("The task plugin instance is not initialized");
|
||||
}
|
||||
// task.handle(taskCallBack);
|
||||
}
|
||||
|
||||
protected void afterExecute() throws TaskException {
|
||||
// if (task == null) {
|
||||
// throw new TaskException("The current task instance is null");
|
||||
// }
|
||||
// sendAlertIfNeeded();
|
||||
//
|
||||
// sendTaskResult();
|
||||
//
|
||||
// WorkerTaskExecutorHolder.remove(taskExecutionContext.getTaskInstanceId());
|
||||
// log.info("Remove the current task execute context from worker cache");
|
||||
// clearTaskExecPathIfNeeded();
|
||||
}
|
||||
|
||||
protected void afterThrowing(Throwable throwable) throws TaskException {
|
||||
// if (cancelTask()) {
|
||||
// log.info("Cancel the task successfully");
|
||||
// }
|
||||
// WorkerTaskExecutorHolder.remove(taskExecutionContext.getTaskInstanceId());
|
||||
// taskExecutionContext.setCurrentExecutionStatus(TaskExecutionStatus.FAILURE);
|
||||
// taskExecutionContext.setEndTime(System.currentTimeMillis());
|
||||
// workerMessageSender.sendMessageWithRetry(taskExecutionContext,
|
||||
// ITaskInstanceExecutionEvent.TaskInstanceExecutionEventType.FINISH);
|
||||
// log.info("Get a exception when execute the task, will send the task status: {} to master: {}",
|
||||
// TaskExecutionStatus.FAILURE.name(), taskExecutionContext.getHost());
|
||||
|
||||
}
|
||||
|
||||
protected boolean cancelTask() {
|
||||
// cancel the task
|
||||
if (task == null) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
task.cancel();
|
||||
// ProcessUtils.cancelApplication(taskExecutionContext);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("Cancel task failed, this will not affect the taskInstance status, but you need to check manual",
|
||||
e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
TaskInstanceLogHeader.printInitializeTaskContextHeader();
|
||||
initializeTask();
|
||||
|
||||
TaskInstanceLogHeader.printLoadTaskInstancePluginHeader();
|
||||
beforeExecute();
|
||||
|
||||
// TaskCallBack taskCallBack = TaskCallbackImpl.builder()
|
||||
// .workerMessageSender(workerMessageSender)
|
||||
// .taskExecutionContext(taskExecutionContext)
|
||||
// .build();
|
||||
|
||||
TaskInstanceLogHeader.printExecuteTaskHeader();
|
||||
// executeTrigger(taskCallBack);
|
||||
|
||||
TaskInstanceLogHeader.printFinalizeTaskHeader();
|
||||
afterExecute();
|
||||
closeLogAppender();
|
||||
} catch (Throwable ex) {
|
||||
log.error("Task execute failed, due to meet an exception", ex);
|
||||
afterThrowing(ex);
|
||||
closeLogAppender();
|
||||
} finally {
|
||||
LogUtils.removeWorkflowAndTaskInstanceIdMDC();
|
||||
LogUtils.removeTaskInstanceLogFullPathMDC();
|
||||
}
|
||||
}
|
||||
|
||||
protected void initializeTask() {
|
||||
log.info("Begin to initialize task");
|
||||
|
||||
long taskStartTime = System.currentTimeMillis();
|
||||
// taskExecutionContext.setStartTime(taskStartTime);
|
||||
log.info("Set task startTime: {}", taskStartTime);
|
||||
|
||||
// String taskAppId = String.format("%s_%s", taskExecutionContext.getProcessInstanceId(),
|
||||
// taskExecutionContext.getTaskInstanceId());
|
||||
// taskExecutionContext.setTaskAppId(taskAppId);
|
||||
// log.info("Set task appId: {}", taskAppId);
|
||||
|
||||
// log.info("End initialize task {}", JSONUtils.toPrettyJsonString(taskExecutionContext));
|
||||
}
|
||||
|
||||
protected void beforeExecute() {
|
||||
}
|
||||
|
||||
protected void sendAlertIfNeeded() {
|
||||
|
||||
}
|
||||
|
||||
protected void sendTaskResult() {
|
||||
|
||||
}
|
||||
|
||||
protected void clearTaskExecPathIfNeeded() {
|
||||
|
||||
}
|
||||
|
||||
protected void closeLogAppender() {
|
||||
|
||||
}
|
||||
|
||||
public @Nullable AbstractTask getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package org.apache.dolphinscheduler.server.master.runner;
|
||||
|
||||
import org.apache.dolphinscheduler.plugin.task.api.utils.LogUtils;
|
||||
import org.apache.dolphinscheduler.server.master.cache.ProcessInstanceExecCacheManager;
|
||||
import org.apache.dolphinscheduler.server.master.config.MasterConfig;
|
||||
import org.apache.dolphinscheduler.server.master.event.StateEvent;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
import org.springframework.util.concurrent.ListenableFutureCallback;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class TriggerExecuteThreadPool extends ThreadPoolTaskExecutor {
|
||||
|
||||
@Autowired
|
||||
private MasterConfig masterConfig;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
this.setDaemon(true);
|
||||
this.setThreadNamePrefix("StreamTaskExecuteThread-");
|
||||
this.setMaxPoolSize(masterConfig.getExecThreads());
|
||||
this.setCorePoolSize(masterConfig.getExecThreads());
|
||||
}
|
||||
|
||||
public void executeEvent(final TriggerExecuteRunnable triggerExecuteRunnable) {
|
||||
// if (!streamTaskExecuteRunnable.isStart() || streamTaskExecuteRunnable.eventSize() == 0) {
|
||||
// return;
|
||||
// }
|
||||
// int taskInstanceId = streamTaskExecuteRunnable.getTaskInstance().getId();
|
||||
// ListenableFuture<?> future = this.submitListenable(streamTaskExecuteRunnable::handleEvents);
|
||||
// future.addCallback(new ListenableFutureCallback() {
|
||||
//
|
||||
// @Override
|
||||
// public void onFailure(Throwable ex) {
|
||||
// LogUtils.setTaskInstanceIdMDC(taskInstanceId);
|
||||
// log.error("Stream task instance events handle failed", ex);
|
||||
// LogUtils.removeTaskInstanceIdMDC();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onSuccess(Object result) {
|
||||
// LogUtils.setTaskInstanceIdMDC(taskInstanceId);
|
||||
// log.info("Stream task instance is finished.");
|
||||
// LogUtils.removeTaskInstanceIdMDC();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
|
@ -58,6 +58,10 @@
|
|||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-task-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-trigger-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
|
|
|
|||
|
|
@ -222,6 +222,11 @@
|
|||
<artifactId>dolphinscheduler-task-remoteshell</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-task-trigger</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-task-plugin</artifactId>
|
||||
<version>dev-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dolphinscheduler-task-trigger</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-spi</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-task-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package org.apache.dolphinscheduler.plugin.task.trigger;
|
||||
|
||||
public class TriggerException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 8155449302457294758L;
|
||||
|
||||
public TriggerException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TriggerException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public TriggerException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.plugin.task.trigger;
|
||||
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class TriggerParameters extends AbstractParameters {
|
||||
|
||||
private String factoryName;
|
||||
private String resourceGroupName;
|
||||
private String pipelineName;
|
||||
private String runId;
|
||||
|
||||
@Override
|
||||
public boolean checkParameters() {
|
||||
return StringUtils.isNotEmpty(factoryName) && StringUtils.isNotEmpty(resourceGroupName)
|
||||
&& StringUtils.isNotEmpty(pipelineName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.plugin.task.trigger;
|
||||
|
||||
public enum TriggerStatus {
|
||||
|
||||
Queued,
|
||||
InProgress,
|
||||
Succeeded,
|
||||
Failed,
|
||||
Canceling,
|
||||
Cancelled,
|
||||
;
|
||||
|
||||
/**
|
||||
* Gets the status property: The status of a pipeline run. Possible values: Queued, InProgress, Succeeded, Failed,
|
||||
* Canceling, Cancelled.
|
||||
*
|
||||
* @return the status value.
|
||||
*/
|
||||
TriggerStatus() {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.plugin.task.trigger;
|
||||
|
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.AbstractRemoteTask;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskConstants;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskException;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Slf4j
|
||||
public class TriggerTask extends AbstractRemoteTask {
|
||||
|
||||
private final TaskExecutionContext taskExecutionContext;
|
||||
private TriggerParameters parameters;
|
||||
|
||||
public TriggerTask(TaskExecutionContext taskExecutionContext) {
|
||||
super(taskExecutionContext);
|
||||
this.taskExecutionContext = taskExecutionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getApplicationIds() throws TaskException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
parameters = JSONUtils.parseObject(taskExecutionContext.getTaskParams(), TriggerParameters.class);
|
||||
log.info("Initialize Datafactory task params {}", JSONUtils.toPrettyJsonString(parameters));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitApplication() throws TaskException {
|
||||
try {
|
||||
// start task
|
||||
exitStatusCode = startDatafactoryTask();
|
||||
setExitStatusCode(exitStatusCode);
|
||||
} catch (Exception e) {
|
||||
setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE);
|
||||
throw new TaskException("data factory start task error", e);
|
||||
}
|
||||
// set runId to the appIds if start success
|
||||
setAppIds(parameters.getRunId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelApplication() throws TaskException {
|
||||
checkApplicationId();
|
||||
exitStatusCode = TaskConstants.EXIT_CODE_KILL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackApplicationStatus() throws TaskException {
|
||||
checkApplicationId();
|
||||
Boolean isFinishedSuccessfully = false;
|
||||
if (!isFinishedSuccessfully) {
|
||||
exitStatusCode = TaskConstants.EXIT_CODE_FAILURE;
|
||||
} else {
|
||||
exitStatusCode = TaskConstants.EXIT_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check datafactory applicationId or get it from appId
|
||||
*/
|
||||
private void checkApplicationId() {
|
||||
}
|
||||
|
||||
public int startDatafactoryTask() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TriggerParameters getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.plugin.task.trigger;
|
||||
|
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskChannel;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parameters.ParametersNode;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parameters.resource.ResourceParametersHelper;
|
||||
|
||||
public class TriggerTaskChannel implements TaskChannel {
|
||||
|
||||
@Override
|
||||
public void cancelApplication(boolean status) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TriggerTask createTask(TaskExecutionContext taskRequest) {
|
||||
return new TriggerTask(taskRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractParameters parseParameters(ParametersNode parametersNode) {
|
||||
return JSONUtils.parseObject(parametersNode.getTaskParams(), TriggerParameters.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceParametersHelper getResources(String parameters) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.plugin.task.trigger;
|
||||
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskChannel;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.TaskChannelFactory;
|
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
|
||||
@AutoService(TaskChannelFactory.class)
|
||||
public class TriggerTaskChannelFactory implements TaskChannelFactory {
|
||||
|
||||
@Override
|
||||
public TaskChannel create() {
|
||||
return new TriggerTaskChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "TRIGGER";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PluginParams> getParams() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.plugin.task.trigger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class TriggerTaskTest {
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -63,6 +63,7 @@
|
|||
<module>dolphinscheduler-task-linkis</module>
|
||||
<module>dolphinscheduler-task-datafactory</module>
|
||||
<module>dolphinscheduler-task-remoteshell</module>
|
||||
<module>dolphinscheduler-task-trigger</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-trigger-plugin</artifactId>
|
||||
<version>dev-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dolphinscheduler-trigger-all</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-trigger-simple</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-trigger-plugin</artifactId>
|
||||
<version>dev-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dolphinscheduler-trigger-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-spi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-annotation</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.enums.TriggerExecutionStatus;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Slf4j
|
||||
public abstract class AbstractTrigger {
|
||||
@Getter
|
||||
@Setter
|
||||
protected Map<String, String> taskOutputParams;
|
||||
|
||||
/**
|
||||
* taskExecutionContext
|
||||
**/
|
||||
protected TriggerExecutionContext triggerExecutionContext;
|
||||
|
||||
protected AbstractTrigger(TriggerExecutionContext triggerExecutionContext) {
|
||||
this.triggerExecutionContext = triggerExecutionContext;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public abstract void handle(TriggerCallBack taskCallBack) throws TriggerException;
|
||||
|
||||
public abstract void cancel() throws TriggerException;
|
||||
|
||||
/**
|
||||
* get task parameters
|
||||
*
|
||||
* @return AbstractParameters
|
||||
*/
|
||||
public abstract AbstractParameters getParameters();
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api;
|
||||
|
||||
public interface TriggerCallBack {
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api;
|
||||
|
||||
public interface TriggerChannel {
|
||||
void cancelApplication(boolean status);
|
||||
|
||||
AbstractTrigger createTrigger(TriggerExecutionContext taskRequest);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.plugin.trigger.api;
|
||||
|
||||
import org.apache.dolphinscheduler.spi.common.UiChannelFactory;
|
||||
import org.apache.dolphinscheduler.spi.plugin.PrioritySPI;
|
||||
import org.apache.dolphinscheduler.spi.plugin.SPIIdentify;
|
||||
|
||||
public interface TriggerChannelFactory extends UiChannelFactory, PrioritySPI {
|
||||
|
||||
TriggerChannel create();
|
||||
|
||||
default SPIIdentify getIdentify() {
|
||||
return SPIIdentify.builder().name(getName()).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,425 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import org.apache.dolphinscheduler.common.constants.DateConstants;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Set;
|
||||
|
||||
public class TriggerConstants {
|
||||
|
||||
private TriggerConstants() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static final String YARN_APPLICATION_REGEX = "application_\\d+_\\d+";
|
||||
|
||||
public static final String FLINK_APPLICATION_REGEX = "JobID \\w+";
|
||||
|
||||
/**
|
||||
* exit code kill
|
||||
*/
|
||||
public static final int EXIT_CODE_KILL = 137;
|
||||
public static final String PID = "pid";
|
||||
|
||||
/**
|
||||
* QUESTION ?
|
||||
*/
|
||||
public static final String QUESTION = "?";
|
||||
|
||||
/**
|
||||
* comma ,
|
||||
*/
|
||||
public static final String COMMA = ",";
|
||||
|
||||
/**
|
||||
* hyphen
|
||||
*/
|
||||
public static final String HYPHEN = "-";
|
||||
|
||||
/**
|
||||
* slash /
|
||||
*/
|
||||
public static final String SLASH = "/";
|
||||
|
||||
/**
|
||||
* COLON :
|
||||
*/
|
||||
public static final String COLON = ":";
|
||||
|
||||
/**
|
||||
* SPACE " "
|
||||
*/
|
||||
public static final String SPACE = " ";
|
||||
|
||||
/**
|
||||
* SINGLE_SLASH /
|
||||
*/
|
||||
public static final String SINGLE_SLASH = "/";
|
||||
|
||||
/**
|
||||
* DOUBLE_SLASH //
|
||||
*/
|
||||
public static final String DOUBLE_SLASH = "//";
|
||||
|
||||
/**
|
||||
* SINGLE_QUOTES "'"
|
||||
*/
|
||||
public static final String SINGLE_QUOTES = "'";
|
||||
/**
|
||||
* DOUBLE_QUOTES "\""
|
||||
*/
|
||||
public static final String DOUBLE_QUOTES = "\"";
|
||||
|
||||
/**
|
||||
* SEMICOLON ;
|
||||
*/
|
||||
public static final String SEMICOLON = ";";
|
||||
|
||||
/**
|
||||
* EQUAL SIGN
|
||||
*/
|
||||
public static final String EQUAL_SIGN = "=";
|
||||
/**
|
||||
* AT SIGN
|
||||
*/
|
||||
public static final String AT_SIGN = "@";
|
||||
/**
|
||||
* UNDERLINE
|
||||
*/
|
||||
public static final String UNDERLINE = "_";
|
||||
|
||||
/**
|
||||
* sleep time
|
||||
*/
|
||||
public static final int SLEEP_TIME_MILLIS = 1000;
|
||||
|
||||
/**
|
||||
* exit code failure
|
||||
*/
|
||||
public static final int EXIT_CODE_FAILURE = -1;
|
||||
|
||||
/**
|
||||
* exit code success
|
||||
*/
|
||||
public static final int EXIT_CODE_SUCCESS = 0;
|
||||
/**
|
||||
* running code
|
||||
*/
|
||||
public static final int RUNNING_CODE = 1;
|
||||
|
||||
public static final String SH = "sh";
|
||||
|
||||
/**
|
||||
* log flush interval?output when reach the interval
|
||||
*/
|
||||
public static final int DEFAULT_LOG_FLUSH_INTERVAL = 1000;
|
||||
|
||||
/**
|
||||
* pstree, get pud and sub pid
|
||||
*/
|
||||
public static final String PSTREE = "pstree";
|
||||
|
||||
public static final String RWXR_XR_X = "rwxr-xr-x";
|
||||
|
||||
/**
|
||||
* date format of yyyyMMddHHmmss
|
||||
*/
|
||||
public static final String PARAMETER_FORMAT_TIME = "yyyyMMddHHmmss";
|
||||
|
||||
/**
|
||||
* new
|
||||
* schedule time
|
||||
*/
|
||||
public static final String PARAMETER_SHECDULE_TIME = "schedule.time";
|
||||
|
||||
/**
|
||||
* system date(yyyyMMddHHmmss)
|
||||
*/
|
||||
public static final String PARAMETER_DATETIME = DateConstants.PARAMETER_DATETIME;
|
||||
|
||||
/**
|
||||
* system date(yyyymmdd) today
|
||||
*/
|
||||
public static final String PARAMETER_CURRENT_DATE = DateConstants.PARAMETER_CURRENT_DATE;
|
||||
|
||||
/**
|
||||
* system date(yyyymmdd) yesterday
|
||||
*/
|
||||
public static final String PARAMETER_BUSINESS_DATE = DateConstants.PARAMETER_BUSINESS_DATE;
|
||||
|
||||
/**
|
||||
* the absolute path of current executing task
|
||||
*/
|
||||
public static final String PARAMETER_TASK_EXECUTE_PATH = "system.task.execute.path";
|
||||
|
||||
/**
|
||||
* the instance id of current task
|
||||
*/
|
||||
public static final String PARAMETER_TASK_INSTANCE_ID = "system.task.instance.id";
|
||||
|
||||
/**
|
||||
* the definition code of current task
|
||||
*/
|
||||
public static final String PARAMETER_TASK_DEFINITION_CODE = "system.task.definition.code";
|
||||
|
||||
/**
|
||||
* the definition name of current task
|
||||
*/
|
||||
public static final String PARAMETER_TASK_DEFINITION_NAME = "system.task.definition.name";
|
||||
|
||||
/**
|
||||
* the instance id of the workflow to which current task belongs
|
||||
*/
|
||||
public static final String PARAMETER_WORKFLOW_INSTANCE_ID = "system.workflow.instance.id";
|
||||
|
||||
/**
|
||||
* the definition code of the workflow to which current task belongs
|
||||
*/
|
||||
public static final String PARAMETER_WORKFLOW_DEFINITION_CODE = "system.workflow.definition.code";
|
||||
|
||||
/**
|
||||
* the definition name of the workflow to which current task belongs
|
||||
*/
|
||||
public static final String PARAMETER_WORKFLOW_DEFINITION_NAME = "system.workflow.definition.name";
|
||||
|
||||
/**
|
||||
* the code of the project to which current task belongs
|
||||
*/
|
||||
public static final String PARAMETER_PROJECT_CODE = "system.project.code";
|
||||
|
||||
/**
|
||||
* the name of the project to which current task belongs
|
||||
*/
|
||||
public static final String PARAMETER_PROJECT_NAME = "system.project.name";
|
||||
/**
|
||||
* month_begin
|
||||
*/
|
||||
public static final String MONTH_BEGIN = "month_begin";
|
||||
/**
|
||||
* add_months
|
||||
*/
|
||||
public static final String ADD_MONTHS = "add_months";
|
||||
/**
|
||||
* month_end
|
||||
*/
|
||||
public static final String MONTH_END = "month_end";
|
||||
/**
|
||||
* week_begin
|
||||
*/
|
||||
public static final String WEEK_BEGIN = "week_begin";
|
||||
/**
|
||||
* week_end
|
||||
*/
|
||||
public static final String WEEK_END = "week_end";
|
||||
/**
|
||||
* this_day
|
||||
*/
|
||||
public static final String THIS_DAY = "this_day";
|
||||
/**
|
||||
* last_day
|
||||
*/
|
||||
public static final String LAST_DAY = "last_day";
|
||||
|
||||
/**
|
||||
* month_first_day
|
||||
*/
|
||||
public static final String MONTH_FIRST_DAY = "month_first_day";
|
||||
|
||||
/**
|
||||
* month_last_day
|
||||
*/
|
||||
public static final String MONTH_LAST_DAY = "month_last_day";
|
||||
|
||||
/**
|
||||
* week_first_day
|
||||
*/
|
||||
public static final String WEEK_FIRST_DAY = "week_first_day";
|
||||
|
||||
/**
|
||||
* week_last_day
|
||||
*/
|
||||
public static final String WEEK_LAST_DAY = "week_last_day";
|
||||
|
||||
/**
|
||||
* year_week
|
||||
*/
|
||||
public static final String YEAR_WEEK = "year_week";
|
||||
/**
|
||||
* timestamp
|
||||
*/
|
||||
public static final String TIMESTAMP = "timestamp";
|
||||
public static final char SUBTRACT_CHAR = '-';
|
||||
public static final char ADD_CHAR = '+';
|
||||
public static final char MULTIPLY_CHAR = '*';
|
||||
public static final char DIVISION_CHAR = '/';
|
||||
public static final char LEFT_BRACE_CHAR = '(';
|
||||
public static final char RIGHT_BRACE_CHAR = ')';
|
||||
public static final String ADD_STRING = "+";
|
||||
public static final String MULTIPLY_STRING = "*";
|
||||
public static final String DIVISION_STRING = "/";
|
||||
public static final String LEFT_BRACE_STRING = "(";
|
||||
public static final char P = 'P';
|
||||
public static final char N = 'N';
|
||||
public static final String SUBTRACT_STRING = "-";
|
||||
public static final String LOCAL_PARAMS_LIST = "localParamsList";
|
||||
public static final String TASK_TYPE = "taskType";
|
||||
public static final String QUEUE = "queue";
|
||||
/**
|
||||
* default display rows
|
||||
*/
|
||||
public static final int DEFAULT_DISPLAY_ROWS = 10;
|
||||
|
||||
/**
|
||||
* jar
|
||||
*/
|
||||
public static final String JAR = "jar";
|
||||
|
||||
/**
|
||||
* hadoop
|
||||
*/
|
||||
public static final String HADOOP = "hadoop";
|
||||
|
||||
/**
|
||||
* -D <property>=<value>
|
||||
*/
|
||||
public static final String D = "-D";
|
||||
|
||||
/**
|
||||
* datasource encryption salt
|
||||
*/
|
||||
public static final String DATASOURCE_ENCRYPTION_SALT_DEFAULT = "!@#$%^&*";
|
||||
public static final String DATASOURCE_ENCRYPTION_ENABLE = "datasource.encryption.enable";
|
||||
public static final String DATASOURCE_ENCRYPTION_SALT = "datasource.encryption.salt";
|
||||
|
||||
/**
|
||||
* kerberos
|
||||
*/
|
||||
public static final String KERBEROS = "kerberos";
|
||||
|
||||
/**
|
||||
* kerberos expire time
|
||||
*/
|
||||
public static final String KERBEROS_EXPIRE_TIME = "kerberos.expire.time";
|
||||
|
||||
/**
|
||||
* java.security.krb5.conf
|
||||
*/
|
||||
public static final String JAVA_SECURITY_KRB5_CONF = "java.security.krb5.conf";
|
||||
|
||||
/**
|
||||
* java.security.krb5.conf.path
|
||||
*/
|
||||
public static final String JAVA_SECURITY_KRB5_CONF_PATH = "java.security.krb5.conf.path";
|
||||
|
||||
/**
|
||||
* loginUserFromKeytab user
|
||||
*/
|
||||
public static final String LOGIN_USER_KEY_TAB_USERNAME = "login.user.keytab.username";
|
||||
|
||||
/**
|
||||
* loginUserFromKeytab path
|
||||
*/
|
||||
public static final String LOGIN_USER_KEY_TAB_PATH = "login.user.keytab.path";
|
||||
|
||||
/**
|
||||
* hadoop.security.authentication
|
||||
*/
|
||||
public static final String HADOOP_SECURITY_AUTHENTICATION = "hadoop.security.authentication";
|
||||
|
||||
/**
|
||||
* hadoop.security.authentication
|
||||
*/
|
||||
public static final String HADOOP_SECURITY_AUTHENTICATION_STARTUP_STATE =
|
||||
"hadoop.security.authentication.startup.state";
|
||||
|
||||
/**
|
||||
* hdfs/s3 configuration
|
||||
* resource.storage.upload.base.path
|
||||
*/
|
||||
public static final String RESOURCE_UPLOAD_PATH = "resource.storage.upload.base.path";
|
||||
|
||||
/**
|
||||
* data.quality.jar.dir
|
||||
*/
|
||||
public static final String DATA_QUALITY_JAR_DIR = "data-quality.jar.dir";
|
||||
|
||||
public static final String TASK_TYPE_CONDITIONS = "CONDITIONS";
|
||||
|
||||
public static final String TASK_TYPE_SWITCH = "SWITCH";
|
||||
|
||||
public static final String TASK_TYPE_SUB_PROCESS = "SUB_PROCESS";
|
||||
|
||||
public static final String TASK_TYPE_DYNAMIC = "DYNAMIC";
|
||||
|
||||
public static final String TASK_TYPE_DEPENDENT = "DEPENDENT";
|
||||
|
||||
public static final String TASK_TYPE_SQL = "SQL";
|
||||
|
||||
public static final String TASK_TYPE_DATA_QUALITY = "DATA_QUALITY";
|
||||
|
||||
public static final Set<String> TASK_TYPE_SET_K8S = Sets.newHashSet("K8S", "KUBEFLOW");
|
||||
|
||||
public static final String TASK_TYPE_BLOCKING = "BLOCKING";
|
||||
|
||||
/**
|
||||
* azure config
|
||||
*/
|
||||
public static final String AZURE_CLIENT_ID = "resource.azure.client.id";
|
||||
public static final String AZURE_CLIENT_SECRET = "resource.azure.client.secret";
|
||||
public static final String AZURE_ACCESS_SUB_ID = "resource.azure.subId";
|
||||
public static final String AZURE_SECRET_TENANT_ID = "resource.azure.tenant.id";
|
||||
public static final String QUERY_INTERVAL = "resource.query.interval";
|
||||
|
||||
/**
|
||||
* aws config
|
||||
*/
|
||||
public static final String AWS_ACCESS_KEY_ID = "resource.aws.access.key.id";
|
||||
public static final String AWS_SECRET_ACCESS_KEY = "resource.aws.secret.access.key";
|
||||
public static final String AWS_REGION = "resource.aws.region";
|
||||
|
||||
/**
|
||||
* alibaba cloud config
|
||||
*/
|
||||
public static final String ALIBABA_CLOUD_ACCESS_KEY_ID = "resource.alibaba.cloud.access.key.id";
|
||||
public static final String ALIBABA_CLOUD_ACCESS_KEY_SECRET = "resource.alibaba.cloud.access.key.secret";
|
||||
public static final String ALIBABA_CLOUD_REGION = "resource.alibaba.cloud.region";
|
||||
|
||||
/**
|
||||
* huawei cloud config
|
||||
*/
|
||||
public static final String HUAWEI_CLOUD_ACCESS_KEY_ID = "resource.huawei.cloud.access.key.id";
|
||||
public static final String HUAWEI_CLOUD_ACCESS_KEY_SECRET = "resource.huawei.cloud.access.key.secret";
|
||||
|
||||
/**
|
||||
* use for k8s task
|
||||
*/
|
||||
public static final String API_VERSION = "batch/v1";
|
||||
public static final String RESTART_POLICY = "Never";
|
||||
public static final String MEMORY = "memory";
|
||||
public static final String CPU = "cpu";
|
||||
public static final String LAYER_LABEL = "k8s.cn/layer";
|
||||
public static final String LAYER_LABEL_VALUE = "batch";
|
||||
public static final String NAME_LABEL = "k8s.cn/name";
|
||||
public static final String TASK_INSTANCE_ID = "taskInstanceId";
|
||||
public static final String MI = "Mi";
|
||||
public static final int JOB_TTL_SECONDS = 300;
|
||||
public static final int LOG_LINES = 500;
|
||||
public static final String NAMESPACE_NAME = "name";
|
||||
public static final String CLUSTER = "cluster";
|
||||
|
||||
/**
|
||||
* spark / flink on k8s label name
|
||||
*/
|
||||
public static final String UNIQUE_LABEL_NAME = "dolphinscheduler-label";
|
||||
|
||||
/**
|
||||
* conda config used by jupyter task plugin
|
||||
*/
|
||||
public static final String CONDA_PATH = "conda.path";
|
||||
|
||||
// Loop task constants
|
||||
public static final Duration DEFAULT_LOOP_STATUS_INTERVAL = Duration.ofSeconds(5L);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api;
|
||||
|
||||
public class TriggerException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 8155449302457294758L;
|
||||
|
||||
public TriggerException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TriggerException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
public TriggerException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* to master/worker task transport
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class TriggerExecutionContext implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1L;
|
||||
|
||||
/**
|
||||
* trigger id
|
||||
*/
|
||||
private int triggerInstanceId;
|
||||
|
||||
/**
|
||||
* trigger name
|
||||
*/
|
||||
private String triggerName;
|
||||
|
||||
/**
|
||||
* trigger first submit time.
|
||||
*/
|
||||
private long firstSubmitTime;
|
||||
|
||||
/**
|
||||
* trigger start time
|
||||
*/
|
||||
private long startTime;
|
||||
|
||||
/**
|
||||
* trigger type
|
||||
*/
|
||||
private String triggerType;
|
||||
|
||||
/**
|
||||
* trigger json
|
||||
*/
|
||||
private String triggerJson;
|
||||
|
||||
/**
|
||||
* processId
|
||||
*/
|
||||
private int processId;
|
||||
|
||||
/**
|
||||
* processCode
|
||||
*/
|
||||
private Long processDefineCode;
|
||||
|
||||
/**
|
||||
* processVersion
|
||||
*/
|
||||
private int processDefineVersion;
|
||||
|
||||
/**
|
||||
* appIds
|
||||
*/
|
||||
private String appIds;
|
||||
|
||||
/**
|
||||
* process instance id
|
||||
*/
|
||||
private int processInstanceId;
|
||||
|
||||
/**
|
||||
* process instance schedule time
|
||||
*/
|
||||
private long scheduleTime;
|
||||
|
||||
/**
|
||||
* process instance global parameters
|
||||
*/
|
||||
private String globalParams;
|
||||
|
||||
/**
|
||||
* execute user id
|
||||
*/
|
||||
private int executorId;
|
||||
|
||||
/**
|
||||
* command type if complement
|
||||
*/
|
||||
private int cmdTypeIfComplement;
|
||||
|
||||
/**
|
||||
* tenant code
|
||||
*/
|
||||
private String tenantCode;
|
||||
|
||||
/**
|
||||
* process define id
|
||||
*/
|
||||
private int processDefineId;
|
||||
|
||||
/**
|
||||
* project id
|
||||
*/
|
||||
private int projectId;
|
||||
|
||||
/**
|
||||
* project code
|
||||
*/
|
||||
private long projectCode;
|
||||
|
||||
/**
|
||||
* taskParams
|
||||
*/
|
||||
private String taskParams;
|
||||
|
||||
/**
|
||||
* environmentConfig
|
||||
*/
|
||||
private String environmentConfig;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.plugin.trigger.api;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.parameters.ParametersNode;
|
||||
import org.apache.dolphinscheduler.spi.plugin.PrioritySPIFactory;
|
||||
|
||||
@Slf4j
|
||||
public class TriggerPluginManager {
|
||||
private static final Map<String, TriggerChannelFactory> taskChannelFactoryMap = new HashMap<>();
|
||||
private static final Map<String, TriggerChannel> taskChannelMap = new HashMap<>();
|
||||
|
||||
private static final AtomicBoolean loadedFlag = new AtomicBoolean(false);
|
||||
|
||||
/**
|
||||
* Load task plugins from classpath.
|
||||
*/
|
||||
public static void loadPlugin() {
|
||||
if (!loadedFlag.compareAndSet(false, true)) {
|
||||
log.warn("The trigger plugin has already been loaded");
|
||||
return;
|
||||
}
|
||||
PrioritySPIFactory<TriggerChannelFactory> prioritySPIFactory = new PrioritySPIFactory<>(TriggerChannelFactory.class);
|
||||
for (Map.Entry<String, TriggerChannelFactory> entry : prioritySPIFactory.getSPIMap().entrySet()) {
|
||||
String factoryName = entry.getKey();
|
||||
TriggerChannelFactory factory = entry.getValue();
|
||||
|
||||
log.info("Registering trigger plugin: {} - {}", factoryName, factory.getClass().getSimpleName());
|
||||
|
||||
taskChannelFactoryMap.put(factoryName, factory);
|
||||
taskChannelMap.put(factoryName, factory.create());
|
||||
|
||||
log.info("Registered trigger plugin: {} - {}", factoryName, factory.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Map<String, TriggerChannel> getTaskChannelMap() {
|
||||
return Collections.unmodifiableMap(taskChannelMap);
|
||||
}
|
||||
|
||||
public static Map<String, TriggerChannelFactory> getTaskChannelFactoryMap() {
|
||||
return Collections.unmodifiableMap(taskChannelFactoryMap);
|
||||
}
|
||||
|
||||
public static TriggerChannel getTaskChannel(String type) {
|
||||
return getTaskChannelMap().get(type);
|
||||
}
|
||||
|
||||
public static boolean checkTaskParameters(ParametersNode parametersNode) {
|
||||
AbstractParameters abstractParameters = getParameters(parametersNode);
|
||||
return abstractParameters != null;
|
||||
}
|
||||
|
||||
public static AbstractParameters getParameters(ParametersNode parametersNode) {
|
||||
String taskType = parametersNode.getTaskType();
|
||||
if (Objects.isNull(taskType)) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api.enums;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum TriggerExecutionStatus {
|
||||
|
||||
SUBMITTED_SUCCESS(0, "submit success"),
|
||||
RUNNING_EXECUTION(1, "running"),
|
||||
PAUSE(3, "pause"),
|
||||
STOP(5, "stop"),
|
||||
FAILURE(6, "failure"),
|
||||
SUCCESS(7, "success"),
|
||||
NEED_FAULT_TOLERANCE(8, "need fault tolerance"),
|
||||
KILL(9, "kill"),
|
||||
DELAY_EXECUTION(12, "delay execution"),
|
||||
FORCED_SUCCESS(13, "forced success"),
|
||||
DISPATCH(17, "dispatch"),
|
||||
|
||||
;
|
||||
|
||||
private static final Map<Integer, TriggerExecutionStatus> CODE_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (TriggerExecutionStatus executionStatus : TriggerExecutionStatus.values()) {
|
||||
CODE_MAP.put(executionStatus.getCode(), executionStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get <code>TaskExecutionStatus</code> by code, if the code is invalidated will throw {@link IllegalArgumentException}.
|
||||
*/
|
||||
public static TriggerExecutionStatus of(int code) {
|
||||
TriggerExecutionStatus taskExecutionStatus = CODE_MAP.get(code);
|
||||
if (taskExecutionStatus == null) {
|
||||
throw new IllegalArgumentException(String.format("The task execution status code: %s is invalidated",
|
||||
code));
|
||||
}
|
||||
return taskExecutionStatus;
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return this == RUNNING_EXECUTION;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return this == TriggerExecutionStatus.SUCCESS;
|
||||
}
|
||||
|
||||
public boolean isForceSuccess() {
|
||||
return this == TriggerExecutionStatus.FORCED_SUCCESS;
|
||||
}
|
||||
|
||||
public boolean isKill() {
|
||||
return this == TriggerExecutionStatus.KILL;
|
||||
}
|
||||
|
||||
public boolean isFailure() {
|
||||
return this == TriggerExecutionStatus.FAILURE || this == NEED_FAULT_TOLERANCE;
|
||||
}
|
||||
|
||||
public boolean isPause() {
|
||||
return this == TriggerExecutionStatus.PAUSE;
|
||||
}
|
||||
|
||||
public boolean isStop() {
|
||||
return this == TriggerExecutionStatus.STOP;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return isSuccess() || isKill() || isFailure() || isPause() || isStop() || isForceSuccess();
|
||||
}
|
||||
|
||||
public boolean isNeedFaultTolerance() {
|
||||
return this == NEED_FAULT_TOLERANCE;
|
||||
}
|
||||
|
||||
public boolean shouldFailover() {
|
||||
return SUBMITTED_SUCCESS == this
|
||||
|| DISPATCH == this
|
||||
|| RUNNING_EXECUTION == this
|
||||
|| DELAY_EXECUTION == this;
|
||||
}
|
||||
|
||||
@EnumValue
|
||||
private final int code;
|
||||
private final String desc;
|
||||
|
||||
TriggerExecutionStatus(int code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TaskExecutionStatus{" + "code=" + code + ", desc='" + desc + '\'' + '}';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api.parameters;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils;
|
||||
|
||||
@Getter
|
||||
@Slf4j
|
||||
public class AbstractParameters implements IParameters {
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api.parameters;
|
||||
|
||||
public interface IParameters {
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.api.parameters;
|
||||
|
||||
public class ParametersNode {
|
||||
|
||||
private String taskType;
|
||||
|
||||
private String taskParams;
|
||||
|
||||
private String dependence;
|
||||
|
||||
private String switchResult;
|
||||
|
||||
public static ParametersNode.ParametersNodeBuilder builder() {
|
||||
return new ParametersNode.ParametersNodeBuilder();
|
||||
}
|
||||
|
||||
public static class ParametersNodeBuilder {
|
||||
|
||||
private String taskType;
|
||||
|
||||
private String taskParams;
|
||||
|
||||
private String dependence;
|
||||
|
||||
private String switchResult;
|
||||
|
||||
public ParametersNodeBuilder taskType(String taskType) {
|
||||
this.taskType = taskType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParametersNodeBuilder taskParams(String taskParams) {
|
||||
this.taskParams = taskParams;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParametersNodeBuilder dependence(String dependence) {
|
||||
this.dependence = dependence;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParametersNodeBuilder switchResult(String switchResult) {
|
||||
this.switchResult = switchResult;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParametersNode build() {
|
||||
return new ParametersNode(this.taskType, this.taskParams, this.dependence, this.switchResult);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ParametersNode() {
|
||||
|
||||
}
|
||||
|
||||
public ParametersNode(String taskType, String taskParams, String dependence, String switchResult) {
|
||||
this.taskType = taskType;
|
||||
this.taskParams = taskParams;
|
||||
this.dependence = dependence;
|
||||
this.switchResult = switchResult;
|
||||
}
|
||||
|
||||
public String getTaskType() {
|
||||
return taskType;
|
||||
}
|
||||
|
||||
public void setTaskType(String taskType) {
|
||||
this.taskType = taskType;
|
||||
}
|
||||
|
||||
public String getTaskParams() {
|
||||
return taskParams;
|
||||
}
|
||||
|
||||
public void setTaskParams(String taskParams) {
|
||||
this.taskParams = taskParams;
|
||||
}
|
||||
|
||||
public String getDependence() {
|
||||
return dependence;
|
||||
}
|
||||
|
||||
public void setDependence(String dependence) {
|
||||
this.dependence = dependence;
|
||||
}
|
||||
|
||||
public String getSwitchResult() {
|
||||
return switchResult;
|
||||
}
|
||||
|
||||
public void setSwitchResult(String switchResult) {
|
||||
this.switchResult = switchResult;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-trigger-plugin</artifactId>
|
||||
<version>dev-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dolphinscheduler-trigger-simple</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-spi</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-trigger-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.simple;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.AbstractTrigger;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerCallBack;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerException;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerExecutionContext;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
|
||||
|
||||
@Slf4j
|
||||
public class SimpleTrigger extends AbstractTrigger {
|
||||
|
||||
private SimpleTriggerPatameters simpleTriggerPatameters;
|
||||
|
||||
private TriggerExecutionContext triggerExecutionContext;
|
||||
|
||||
public SimpleTrigger(TriggerExecutionContext triggerExecutionContext) {
|
||||
super(triggerExecutionContext);
|
||||
|
||||
this.triggerExecutionContext = triggerExecutionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void handle(TriggerCallBack triggerCallBack) throws TriggerException {
|
||||
try {
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("shell task error", e);
|
||||
throw new TriggerException("Execute shell task error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() throws TriggerException {
|
||||
// cancel process
|
||||
try {
|
||||
} catch (Exception e) {
|
||||
throw new TriggerException("cancel application error", e);
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractParameters getParameters() {
|
||||
return simpleTriggerPatameters;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.simple;
|
||||
|
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerChannel;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerExecutionContext;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.parameters.ParametersNode;
|
||||
|
||||
public class SimpleTriggerChannel implements TriggerChannel {
|
||||
|
||||
@Override
|
||||
public void cancelApplication(boolean status) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleTrigger createTrigger(TriggerExecutionContext taskRequest) {
|
||||
return new SimpleTrigger(taskRequest);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.simple;
|
||||
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerChannel;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.TriggerChannelFactory;
|
||||
import org.apache.dolphinscheduler.spi.params.base.ParamsOptions;
|
||||
import org.apache.dolphinscheduler.spi.params.base.PluginParams;
|
||||
import org.apache.dolphinscheduler.spi.params.base.Validate;
|
||||
import org.apache.dolphinscheduler.spi.params.input.InputParam;
|
||||
import org.apache.dolphinscheduler.spi.params.radio.RadioParam;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
|
||||
@AutoService(TriggerChannelFactory.class)
|
||||
public class SimpleTriggerChannelFactory implements TriggerChannelFactory {
|
||||
|
||||
@Override
|
||||
public TriggerChannel create() {
|
||||
return new SimpleTriggerChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SIMPLE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PluginParams> getParams() {
|
||||
List<PluginParams> paramsList = new ArrayList<>();
|
||||
|
||||
InputParam nodeName = InputParam.newBuilder("name", "$t('Node name')")
|
||||
.addValidate(Validate.newBuilder()
|
||||
.setRequired(true)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
RadioParam runFlag = RadioParam.newBuilder("runFlag", "RUN_FLAG")
|
||||
.addParamsOptions(new ParamsOptions("NORMAL", "NORMAL", false))
|
||||
.addParamsOptions(new ParamsOptions("FORBIDDEN", "FORBIDDEN", false))
|
||||
.build();
|
||||
|
||||
paramsList.add(nodeName);
|
||||
paramsList.add(runFlag);
|
||||
return paramsList;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package org.apache.dolphinscheduler.plugin.trigger.simple;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.apache.dolphinscheduler.plugin.trigger.api.parameters.AbstractParameters;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class SimpleTriggerPatameters extends AbstractParameters {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler</artifactId>
|
||||
<version>dev-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>dolphinscheduler-trigger-plugin</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>dolphinscheduler-trigger-all</module>
|
||||
<module>dolphinscheduler-trigger-api</module>
|
||||
<module>dolphinscheduler-trigger-simple</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dolphinscheduler</groupId>
|
||||
<artifactId>dolphinscheduler-bom</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
||||
|
|
@ -36,6 +36,7 @@ const Sidebar = defineComponent({
|
|||
const defaultExpandedKeys = [
|
||||
'workflow',
|
||||
'task',
|
||||
'trigger',
|
||||
'udf-manage',
|
||||
'service-manage',
|
||||
'statistical-manage',
|
||||
|
|
|
|||
|
|
@ -167,6 +167,23 @@ export function useDataList() {
|
|||
payload: { projectName: projectName }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: t('menu.trigger'),
|
||||
key: 'trigger',
|
||||
icon: renderIcon(SettingOutlined),
|
||||
children: [
|
||||
{
|
||||
label: t('menu.trigger_definition'),
|
||||
key: `/projects/${projectCode}/trigger/definitions`,
|
||||
payload: { projectName: projectName }
|
||||
},
|
||||
{
|
||||
label: t('menu.trigger_instance'),
|
||||
key: `/projects/${projectCode}/trigger/instances`,
|
||||
payload: { projectName: projectName }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ export default {
|
|||
task: 'Task',
|
||||
task_instance: 'Task Instance',
|
||||
task_definition: 'Task Definition',
|
||||
trigger: 'Trigger',
|
||||
trigger_instance: 'Trigger Instance',
|
||||
trigger_definition: 'Trigger Definition',
|
||||
file_manage: 'File Manage',
|
||||
udf_manage: 'UDF Manage',
|
||||
resource_manage: 'Resource Manage',
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ export default {
|
|||
modify_user: 'Modify User',
|
||||
operation: 'Operation',
|
||||
edit: 'Edit',
|
||||
trigger: '触发',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
start: 'Start',
|
||||
|
|
@ -323,6 +324,12 @@ export default {
|
|||
delete_validate_dependent_tasks_desc:
|
||||
'The downstream dependent tasks exists. You can not delete the task.'
|
||||
},
|
||||
trigger: {
|
||||
trigger: 'Trigger',
|
||||
create_trigger: 'Create Trigger',
|
||||
trigger_definition: 'Trigger Definition',
|
||||
trigger_name: 'Trigger Name'
|
||||
},
|
||||
dag: {
|
||||
create: 'Create Workflow',
|
||||
search: 'Search',
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ export default {
|
|||
task: '任务',
|
||||
task_instance: '任务实例',
|
||||
task_definition: '任务定义',
|
||||
trigger: '触发器',
|
||||
trigger_instance: '触发器实例',
|
||||
trigger_definition: '触发器定义',
|
||||
file_manage: '文件管理',
|
||||
udf_manage: 'UDF管理',
|
||||
resource_manage: '资源管理',
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ export default {
|
|||
modify_user: '修改用户',
|
||||
operation: '操作',
|
||||
edit: '编辑',
|
||||
trigger: '触发',
|
||||
confirm: '确定',
|
||||
cancel: '取消',
|
||||
start: '运行',
|
||||
|
|
@ -319,6 +320,12 @@ export default {
|
|||
remove_task_cache: '清除缓存',
|
||||
delete_validate_dependent_tasks_desc: '下游存在依赖,你不能删除该任务定义'
|
||||
},
|
||||
trigger: {
|
||||
trigger: '触发器',
|
||||
create_trigger: '创建触发器',
|
||||
trigger_definition: '触发器定义',
|
||||
trigger_name: '触发器名称'
|
||||
},
|
||||
dag: {
|
||||
create: '创建工作流',
|
||||
search: '搜索',
|
||||
|
|
|
|||
|
|
@ -201,6 +201,28 @@ export default {
|
|||
auth: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/projects/:projectCode/trigger/definitions',
|
||||
name: 'trigger-definition',
|
||||
component: components['projects-trigger-definition'],
|
||||
meta: {
|
||||
title: '触发器定义',
|
||||
activeMenu: 'projects',
|
||||
showSide: true,
|
||||
auth: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/projects/:projectCode/trigger/instances',
|
||||
name: 'trigger-instance',
|
||||
component: components['projects-trigger-instance'],
|
||||
meta: {
|
||||
title: '触发器实例',
|
||||
activeMenu: 'projects',
|
||||
showSide: true,
|
||||
auth: []
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/projects/:projectCode/workflow-definition/tree/:definitionCode',
|
||||
name: 'workflow-definition-tree',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { axios } from '@/service/service'
|
||||
import {
|
||||
PageReq,
|
||||
ProjectCodeReq,
|
||||
TaskDefinitionListReq,
|
||||
TaskDefinitionJsonReq,
|
||||
CodeReq,
|
||||
TaskDefinitionJsonObjReq,
|
||||
ReleaseStateReq,
|
||||
VersionReq,
|
||||
ISingleSaveReq,
|
||||
TaskDefinitionReq
|
||||
} from './types'
|
||||
|
||||
export function queryTriggerDefinitionListPaging(
|
||||
params: TaskDefinitionListReq,
|
||||
projectCode: ProjectCodeReq
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode.projectCode}/task-definition`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function save(
|
||||
data: TaskDefinitionJsonReq,
|
||||
projectCode: ProjectCodeReq
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/task-definition`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function genTaskCodeList(num: number, projectCode: number) {
|
||||
return axios.request<unknown, number[]>({
|
||||
url: `/projects/${projectCode}/task-definition/gen-task-codes`,
|
||||
method: 'get',
|
||||
params: {
|
||||
genNum: num
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function queryTriggerDefinitionByCode(
|
||||
code: number,
|
||||
projectCode: number
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/task-definition/${code}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function updateTrigger(
|
||||
projectCode: number,
|
||||
code: number,
|
||||
data: TaskDefinitionJsonObjReq
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/task-definition/${code}`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteTriggerDefinition(
|
||||
code: CodeReq,
|
||||
projectCode: ProjectCodeReq
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode.projectCode}/task-definition/${code.code}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function releaseTaskDefinition(
|
||||
data: ReleaseStateReq,
|
||||
code: number,
|
||||
projectCode: number
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/task-definition/${code}/release`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function queryTaskVersions(
|
||||
params: PageReq,
|
||||
code: CodeReq,
|
||||
projectCode: ProjectCodeReq
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function switchVersion(
|
||||
version: VersionReq,
|
||||
code: CodeReq,
|
||||
projectCode: ProjectCodeReq
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions/${version.version}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteVersion(
|
||||
version: VersionReq,
|
||||
code: CodeReq,
|
||||
projectCode: ProjectCodeReq
|
||||
): any {
|
||||
return axios({
|
||||
url: `/projects/${projectCode.projectCode}/task-definition/${code.code}/versions/${version.version}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function saveSingle(projectCode: number, data: ISingleSaveReq) {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/task-definition/save-single`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateWithUpstream(
|
||||
projectCode: number,
|
||||
code: number,
|
||||
data: ISingleSaveReq
|
||||
) {
|
||||
return axios({
|
||||
url: `/projects/${projectCode}/task-definition/${code}/with-upstream`,
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function startTaskDefinition(
|
||||
projectCode: number,
|
||||
code: number,
|
||||
data: TaskDefinitionReq
|
||||
) {
|
||||
return axios({
|
||||
url: `projects/${projectCode}/executors/task-instance/${code}/start`,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
interface PageReq {
|
||||
pageNo: number
|
||||
pageSize: number
|
||||
}
|
||||
|
||||
interface ListReq extends PageReq {
|
||||
searchVal?: string
|
||||
}
|
||||
|
||||
interface ProjectCodeReq {
|
||||
projectCode: number
|
||||
}
|
||||
|
||||
interface TaskDefinitionListReq extends ListReq {
|
||||
taskType?: string
|
||||
userId?: number
|
||||
taskExecuteType?: 'BATCH' | 'STREAM'
|
||||
}
|
||||
|
||||
interface TaskDefinitionJsonReq {
|
||||
taskDefinitionJson: string
|
||||
}
|
||||
|
||||
interface CodeReq {
|
||||
code: any
|
||||
}
|
||||
|
||||
interface TaskDefinitionJsonObjReq {
|
||||
taskDefinitionJsonObj: string
|
||||
taskExecuteType?: string
|
||||
}
|
||||
|
||||
interface ReleaseStateReq {
|
||||
releaseState: 'OFFLINE' | 'ONLINE'
|
||||
}
|
||||
|
||||
interface VersionReq {
|
||||
version: number
|
||||
}
|
||||
|
||||
interface TaskDefinitionItem {
|
||||
taskName: string
|
||||
taskCode: any
|
||||
taskVersion: number
|
||||
taskType: string
|
||||
taskCreateTime: string
|
||||
taskUpdateTime: string
|
||||
processDefinitionCode: any
|
||||
processDefinitionVersion: number
|
||||
processDefinitionName: string
|
||||
processReleaseState: string
|
||||
upstreamTaskMap: any
|
||||
upstreamTaskCode: number
|
||||
upstreamTaskName: string
|
||||
}
|
||||
|
||||
interface TaskDefinitionRes {
|
||||
totalList: TaskDefinitionItem[]
|
||||
total: number
|
||||
totalPage: number
|
||||
pageSize: number
|
||||
currentPage: number
|
||||
start: number
|
||||
}
|
||||
|
||||
interface TaskDefinitionVersionItem {
|
||||
id: number
|
||||
code: number
|
||||
name: string
|
||||
version: number
|
||||
description: string
|
||||
projectCode: number
|
||||
userId: number
|
||||
taskType: string
|
||||
taskParams: any
|
||||
taskParamList: any[]
|
||||
taskParamMap: any
|
||||
flag: string
|
||||
taskPriority: string
|
||||
userName?: any
|
||||
projectName?: any
|
||||
workerGroup: string
|
||||
environmentCode: number
|
||||
failRetryTimes: number
|
||||
failRetryInterval: number
|
||||
timeoutFlag: string
|
||||
timeoutNotifyStrategy?: any
|
||||
timeout: number
|
||||
delayTime: number
|
||||
resourceIds: string
|
||||
createTime: string
|
||||
updateTime: string
|
||||
modifyBy?: any
|
||||
taskGroupId: number
|
||||
taskGroupPriority: number
|
||||
operator: number
|
||||
operateTime: string
|
||||
dependence: string
|
||||
}
|
||||
|
||||
interface TaskDefinitionVersionRes {
|
||||
totalList: TaskDefinitionVersionItem[]
|
||||
total: number
|
||||
totalPage: number
|
||||
pageSize: number
|
||||
currentPage: number
|
||||
start: number
|
||||
}
|
||||
|
||||
interface ISingleSaveReq {
|
||||
processDefinitionCode?: string
|
||||
upstreamCodes: string
|
||||
taskDefinitionJsonObj: string
|
||||
}
|
||||
|
||||
interface TaskDefinitionReq {
|
||||
version: number
|
||||
warningType: string
|
||||
warningGroupId: number
|
||||
workerGroup?: string
|
||||
environmentCode?: number
|
||||
startParams?: string
|
||||
dryRun?: number
|
||||
}
|
||||
|
||||
export {
|
||||
PageReq,
|
||||
ListReq,
|
||||
ProjectCodeReq,
|
||||
TaskDefinitionListReq,
|
||||
TaskDefinitionJsonReq,
|
||||
CodeReq,
|
||||
TaskDefinitionJsonObjReq,
|
||||
ReleaseStateReq,
|
||||
VersionReq,
|
||||
TaskDefinitionItem,
|
||||
TaskDefinitionRes,
|
||||
TaskDefinitionVersionItem,
|
||||
TaskDefinitionVersionRes,
|
||||
ISingleSaveReq,
|
||||
TaskDefinitionReq
|
||||
}
|
||||
|
|
@ -60,6 +60,8 @@ type TaskType =
|
|||
| 'DATA_FACTORY'
|
||||
| 'REMOTESHELL'
|
||||
|
||||
type TriggerType = 'SIMPLE' | 'TIMER' | 'KAFKA'
|
||||
|
||||
type ProgramType = 'JAVA' | 'SCALA' | 'PYTHON'
|
||||
|
||||
type DependentResultType = {
|
||||
|
|
@ -113,6 +115,7 @@ export {
|
|||
BDependentResultType,
|
||||
IMainJar,
|
||||
TaskType,
|
||||
TriggerType,
|
||||
ITaskType,
|
||||
ITaskTypeItem,
|
||||
TaskTypeState,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
defineComponent,
|
||||
PropType,
|
||||
ref,
|
||||
watch,
|
||||
nextTick,
|
||||
provide,
|
||||
computed,
|
||||
h,
|
||||
Ref,
|
||||
onMounted
|
||||
} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Modal from '@/components/modal'
|
||||
import Detail from './detail'
|
||||
import { formatModel } from './format-data'
|
||||
import {
|
||||
HistoryOutlined,
|
||||
ProfileOutlined,
|
||||
QuestionCircleTwotone,
|
||||
BranchesOutlined
|
||||
} from '@vicons/antd'
|
||||
import { NIcon } from 'naive-ui'
|
||||
import { Router, useRouter } from 'vue-router'
|
||||
import { querySubProcessInstanceByTaskCode } from '@/service/modules/process-instances'
|
||||
import { useTaskNodeStore } from '@/store/project/task-node'
|
||||
import type {
|
||||
ITriggerData,
|
||||
ITriggerType,
|
||||
EditWorkflowDefinition,
|
||||
IWorkflowTaskInstance,
|
||||
WorkflowInstance
|
||||
} from './types'
|
||||
import { queryProjectPreferenceByProjectCode } from '@/service/modules/projects-preference'
|
||||
import { INodeData } from './types'
|
||||
|
||||
const props = {
|
||||
show: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
data: {
|
||||
type: Object as PropType<ITriggerData>,
|
||||
default: { code: 0, taskType: 'SHELL', name: '' }
|
||||
},
|
||||
projectCode: {
|
||||
type: Number as PropType<number>,
|
||||
required: true,
|
||||
default: 0
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean as PropType<boolean>,
|
||||
default: false
|
||||
},
|
||||
from: {
|
||||
type: Number as PropType<number>,
|
||||
default: 0
|
||||
},
|
||||
definition: {
|
||||
type: Object as PropType<Ref<EditWorkflowDefinition>>
|
||||
},
|
||||
processInstance: {
|
||||
type: Object as PropType<WorkflowInstance>
|
||||
},
|
||||
taskInstance: {
|
||||
type: Object as PropType<IWorkflowTaskInstance>
|
||||
},
|
||||
saving: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
|
||||
const NodeDetailModal = defineComponent({
|
||||
name: 'NodeDetailModal',
|
||||
props,
|
||||
emits: ['cancel', 'submit', 'viewLog'],
|
||||
setup(props, { emit }) {
|
||||
const { t, locale } = useI18n()
|
||||
const router: Router = useRouter()
|
||||
const taskStore = useTaskNodeStore()
|
||||
|
||||
const renderIcon = (icon: any) => {
|
||||
return () => h(NIcon, null, { default: () => h(icon) })
|
||||
}
|
||||
const detailRef = ref()
|
||||
|
||||
const onConfirm = async () => {
|
||||
await detailRef.value.value.validate()
|
||||
emit('submit', { data: detailRef.value.value.getValues() })
|
||||
}
|
||||
const onCancel = () => {
|
||||
emit('cancel')
|
||||
}
|
||||
|
||||
const headerLinks = ref([] as any)
|
||||
const projectPreferences = ref({} as any)
|
||||
|
||||
const handleViewLog = () => {
|
||||
if (props.taskInstance) {
|
||||
emit('viewLog', props.taskInstance.id, props.taskInstance.taskType)
|
||||
}
|
||||
}
|
||||
|
||||
const initProjectPreferences = (projectCode: number) => {
|
||||
queryProjectPreferenceByProjectCode(projectCode).then((result: any) => {
|
||||
if (result?.preferences && result.state === 1) {
|
||||
projectPreferences.value = JSON.parse(result.preferences)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const restructureNodeData = (data: INodeData) => {
|
||||
if (!data?.id) {
|
||||
for (const item in projectPreferences.value) {
|
||||
if (projectPreferences.value[item] !== null && item in data) {
|
||||
Object.assign(data, { item: projectPreferences.value[item] })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const initHeaderLinks = (processInstance: any, taskType?: ITriggerType) => {
|
||||
headerLinks.value = [
|
||||
{
|
||||
text: t('project.node.instructions'),
|
||||
show: !!(taskType),
|
||||
action: () => {
|
||||
let linkedTaskType = taskType?.toLowerCase().replace('_', '-')
|
||||
if (taskType === 'PROCEDURE') linkedTaskType = 'stored-procedure'
|
||||
const helpUrl =
|
||||
'https://dolphinscheduler.apache.org/' +
|
||||
locale.value.toLowerCase().replace('_', '-') +
|
||||
'/docs/latest/user_doc/guide/task/' +
|
||||
linkedTaskType +
|
||||
'.html'
|
||||
window.open(helpUrl)
|
||||
},
|
||||
icon: renderIcon(QuestionCircleTwotone)
|
||||
},
|
||||
{
|
||||
text: t('project.node.view_history'),
|
||||
show: !!props.taskInstance,
|
||||
action: () => {
|
||||
router.push({
|
||||
name: 'task-instance',
|
||||
query: {
|
||||
taskCode: props.data.code
|
||||
}
|
||||
})
|
||||
},
|
||||
icon: renderIcon(HistoryOutlined)
|
||||
},
|
||||
{
|
||||
text: t('project.node.view_log'),
|
||||
show: !!props.taskInstance,
|
||||
action: () => {
|
||||
handleViewLog()
|
||||
},
|
||||
icon: renderIcon(ProfileOutlined)
|
||||
},
|
||||
{
|
||||
text: t('project.node.enter_this_child_node'),
|
||||
show:
|
||||
props.data.taskType === 'SUB_PROCESS' ||
|
||||
props.data.taskType === 'DYNAMIC',
|
||||
disabled:
|
||||
!props.data.id ||
|
||||
(router.currentRoute.value.name === 'workflow-instance-detail' &&
|
||||
!props.taskInstance),
|
||||
action: () => {
|
||||
if (router.currentRoute.value.name === 'workflow-instance-detail') {
|
||||
querySubProcessInstanceByTaskCode(
|
||||
{ taskId: props.taskInstance?.id },
|
||||
{ projectCode: props.projectCode }
|
||||
).then((res: any) => {
|
||||
router.push({
|
||||
name: 'workflow-instance-detail',
|
||||
params: { id: res.subProcessInstanceId },
|
||||
query: { code: props.data.taskParams?.processDefinitionCode }
|
||||
})
|
||||
})
|
||||
} else {
|
||||
router.push({
|
||||
name: 'workflow-definition-detail',
|
||||
params: { code: props.data.taskParams?.processDefinitionCode }
|
||||
})
|
||||
}
|
||||
},
|
||||
icon: renderIcon(BranchesOutlined)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const onTaskTypeChange = (taskType: ITriggerType) => {
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
props.data.taskType = taskType
|
||||
initHeaderLinks(props.processInstance, props.data.taskType)
|
||||
}
|
||||
|
||||
provide(
|
||||
'data',
|
||||
computed(() => ({
|
||||
projectCode: props.projectCode,
|
||||
data: props.data,
|
||||
from: props.from,
|
||||
readonly: props.readonly,
|
||||
definition: props.definition
|
||||
}))
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
initProjectPreferences(props.projectCode)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => [props.show, props.data],
|
||||
async () => {
|
||||
if (!props.show) return
|
||||
initHeaderLinks(props.processInstance, props.data.taskType)
|
||||
taskStore.init()
|
||||
const nodeData = formatModel(props.data)
|
||||
await nextTick()
|
||||
restructureNodeData(nodeData)
|
||||
detailRef.value.value.setValues(nodeData)
|
||||
}
|
||||
)
|
||||
|
||||
return () => (
|
||||
<Modal
|
||||
show={props.show}
|
||||
title={
|
||||
props.from === 1
|
||||
? `${t('project.task.current_task_settings')}`
|
||||
: `${t('project.node.current_node_settings')}`
|
||||
}
|
||||
onConfirm={onConfirm}
|
||||
confirmLoading={props.saving}
|
||||
confirmDisabled={props.readonly}
|
||||
onCancel={onCancel}
|
||||
headerLinks={headerLinks}
|
||||
>
|
||||
<Detail
|
||||
ref={detailRef}
|
||||
onTaskTypeChange={onTaskTypeChange}
|
||||
key={props.data.triggerType}
|
||||
/>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default NodeDetailModal
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { defineComponent, ref, watch, inject, Ref, unref } from 'vue'
|
||||
import Form from '@/components/form'
|
||||
import { useTask } from './use-task'
|
||||
import { useTaskNodeStore } from '@/store/project/task-node'
|
||||
import type { ITaskData, EditWorkflowDefinition } from './types'
|
||||
|
||||
interface IDetailPanel {
|
||||
projectCode: number
|
||||
data: ITaskData
|
||||
readonly: false
|
||||
from: number
|
||||
detailRef?: Ref
|
||||
definition?: EditWorkflowDefinition
|
||||
}
|
||||
|
||||
const NodeDetail = defineComponent({
|
||||
name: 'NodeDetail',
|
||||
emits: ['taskTypeChange'],
|
||||
setup(props, { expose, emit }) {
|
||||
const taskStore = useTaskNodeStore()
|
||||
|
||||
const formRef = ref()
|
||||
const detailData: IDetailPanel = inject('data') || {
|
||||
projectCode: 0,
|
||||
data: {
|
||||
taskType: 'SHELL'
|
||||
},
|
||||
readonly: false,
|
||||
from: 0
|
||||
}
|
||||
const { data, projectCode, from, readonly, definition } = unref(detailData)
|
||||
|
||||
const { elementsRef, rulesRef, model } = useTask({
|
||||
data,
|
||||
projectCode,
|
||||
from,
|
||||
readonly,
|
||||
definition
|
||||
})
|
||||
watch(
|
||||
() => model.taskType,
|
||||
async (taskType) => {
|
||||
taskStore.updateName(model.name || '')
|
||||
emit('taskTypeChange', taskType)
|
||||
}
|
||||
)
|
||||
|
||||
expose(formRef)
|
||||
|
||||
return () => (
|
||||
<Form
|
||||
ref={formRef}
|
||||
meta={{
|
||||
model,
|
||||
rules: rulesRef.value,
|
||||
elements: elementsRef.value,
|
||||
disabled: unref(readonly)
|
||||
}}
|
||||
layout={{
|
||||
xGap: 10
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default NodeDetail
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { useName } from './use-name'
|
||||
export { useRunFlag } from './use-run-flag'
|
||||
export { useCache } from './use-cache'
|
||||
export { useDescription } from './use-description'
|
||||
export { useTaskPriority } from './use-task-priority'
|
||||
export { useWorkerGroup } from './use-worker-group'
|
||||
export { useEnvironmentName } from './use-environment-name'
|
||||
export { useTaskGroup } from './use-task-group'
|
||||
export { useFailed } from './use-failed'
|
||||
export { useResourceLimit } from './use-resource-limit'
|
||||
export { useDelayTime } from './use-delay-time'
|
||||
export { useTimeoutAlarm } from './use-timeout-alarm'
|
||||
export { usePreTasks } from './use-pre-tasks'
|
||||
export { useTaskType } from './use-task-type'
|
||||
export { useProcessName } from './use-process-name'
|
||||
export { useChildNode } from './use-child-node'
|
||||
export { useTargetTaskName } from './use-target-task-name'
|
||||
export { useDatasource } from './use-datasource'
|
||||
export { useSqlType } from './use-sql-type'
|
||||
export { useProcedure } from './use-procedure'
|
||||
export { useCustomParams } from './use-custom-params'
|
||||
export { useCustomLabels } from './use-custom-labels'
|
||||
export { useNodeSelectors } from './use-node-selectors'
|
||||
export { useSourceType } from './use-sqoop-source-type'
|
||||
export { useTargetType } from './use-sqoop-target-type'
|
||||
export { useRelationCustomParams } from './use-relation-custom-params'
|
||||
export { useDependentTimeout } from './use-dependent-timeout'
|
||||
export { useRules } from './use-rules'
|
||||
export { useDeployMode } from './use-deploy-mode'
|
||||
export { useDriverCores } from './use-driver-cores'
|
||||
export { useDriverMemory } from './use-driver-memory'
|
||||
export { useExecutorNumber } from './use-executor-number'
|
||||
export { useExecutorMemory } from './use-executor-memory'
|
||||
export { useExecutorCores } from './use-executor-cores'
|
||||
export { useMainJar } from './use-main-jar'
|
||||
export { useResources } from './use-resources'
|
||||
export { useTaskDefinition } from './use-task-definition'
|
||||
export { useJavaTaskMainJar } from './use-java-task-main-jar'
|
||||
|
||||
export { useShell } from './use-shell'
|
||||
export { useSpark } from './use-spark'
|
||||
export { useMr } from './use-mr'
|
||||
export { useFlink } from './use-flink'
|
||||
export { useHttp } from './use-http'
|
||||
export { useSql } from './use-sql'
|
||||
export { useSqoop } from './use-sqoop'
|
||||
export { useSeaTunnel } from './use-sea-tunnel'
|
||||
export { useSwitch } from './use-switch'
|
||||
export { useDataX } from './use-datax'
|
||||
export { useConditions } from './use-conditions'
|
||||
export { useDependent } from './use-dependent'
|
||||
export { useEmr } from './use-emr'
|
||||
export { useZeppelin } from './use-zeppelin'
|
||||
export { useNamespace } from './use-namespace'
|
||||
export { useK8s } from './use-k8s'
|
||||
export { useJupyter } from './use-jupyter'
|
||||
export { useMlflow } from './use-mlflow'
|
||||
export { useMlflowProjects } from './use-mlflow-projects'
|
||||
export { useMlflowModels } from './use-mlflow-models'
|
||||
export { useOpenmldb } from './use-openmldb'
|
||||
export { useDvc } from './use-dvc'
|
||||
export { useDinky } from './use-dinky'
|
||||
export { useSagemaker } from './use-sagemaker'
|
||||
export { useJava } from './use-java'
|
||||
export { useChunjun } from './use-chunjun'
|
||||
export { useChunjunDeployMode } from './use-chunjun-deploy-mode'
|
||||
export { usePytorch } from './use-pytorch'
|
||||
export { useHiveCli } from './use-hive-cli'
|
||||
export { useDms } from './use-dms'
|
||||
export { useDatasync } from './use-datasync'
|
||||
export { useKubeflow } from './use-kubeflow'
|
||||
export { useLinkis } from './use-linkis'
|
||||
export { useDataFactory } from './use-data-factory'
|
||||
export { useRemoteShell } from './use-remote-shell'
|
||||
export { useDynamic } from './use-dynamic'
|
||||
export { useYarnQueue } from './use-queue'
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useCache(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
return {
|
||||
type: 'switch',
|
||||
field: 'isCache',
|
||||
name: t('project.node.is_cache'),
|
||||
span: 12
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import {
|
||||
querySimpleList,
|
||||
queryProcessDefinitionByCode
|
||||
} from '@/service/modules/process-definition'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useChildNode({
|
||||
model,
|
||||
projectCode,
|
||||
from,
|
||||
processName,
|
||||
code
|
||||
}: {
|
||||
model: { [field: string]: any }
|
||||
projectCode: number
|
||||
from?: number
|
||||
processName?: number
|
||||
code?: number
|
||||
}): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
const options = ref([] as { label: string; value: string }[])
|
||||
const loading = ref(false)
|
||||
|
||||
const getProcessList = async () => {
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
const res = await querySimpleList(projectCode)
|
||||
options.value = res
|
||||
.filter((option: { name: string; code: number }) => option.code !== code)
|
||||
.map((option: { name: string; code: number }) => ({
|
||||
label: option.name,
|
||||
value: option.code
|
||||
}))
|
||||
loading.value = false
|
||||
}
|
||||
const getProcessListByCode = async (processCode: number) => {
|
||||
if (!processCode) return
|
||||
const res = await queryProcessDefinitionByCode(processCode, projectCode)
|
||||
model.definition = res
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (from === 1 && processName) {
|
||||
getProcessListByCode(processName)
|
||||
}
|
||||
getProcessList()
|
||||
})
|
||||
|
||||
return {
|
||||
type: 'select',
|
||||
field: 'processDefinitionCode',
|
||||
span: 24,
|
||||
name: t('project.node.child_node'),
|
||||
props: {
|
||||
loading: loading,
|
||||
filterable: true
|
||||
},
|
||||
options: options,
|
||||
class: 'select-child-node',
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(unuse: any, value: number) {
|
||||
if (!value) {
|
||||
return Error(t('project.node.child_node_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useChunjunDeployMode(span = 24): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
type: 'radio',
|
||||
field: 'deployMode',
|
||||
name: t('project.node.deploy_mode'),
|
||||
options: DEPLOY_MODES,
|
||||
span
|
||||
}
|
||||
}
|
||||
|
||||
export const DEPLOY_MODES = [
|
||||
{
|
||||
label: 'local',
|
||||
value: 'local'
|
||||
},
|
||||
{
|
||||
label: 'standlone',
|
||||
value: 'standlone'
|
||||
},
|
||||
{
|
||||
label: 'yarn-session',
|
||||
value: 'yarn-session'
|
||||
},
|
||||
{
|
||||
label: 'yarn-per-job',
|
||||
value: 'yarn-per-job'
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
import { useChunjunDeployMode } from './'
|
||||
|
||||
export function useChunjun(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
const jsonEditorSpan = ref(0)
|
||||
const customParameterSpan = ref(0)
|
||||
|
||||
const initConstants = () => {
|
||||
jsonEditorSpan.value = 24
|
||||
customParameterSpan.value = 24
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initConstants()
|
||||
})
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'editor',
|
||||
field: 'json',
|
||||
name: t('project.node.chunjun_json_template'),
|
||||
span: jsonEditorSpan,
|
||||
validate: {
|
||||
trigger: ['input', 'trigger'],
|
||||
required: true,
|
||||
message: t('project.node.sql_empty_tips')
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'custom-parameters',
|
||||
field: 'localParams',
|
||||
name: t('project.node.custom_parameters'),
|
||||
span: customParameterSpan,
|
||||
children: [
|
||||
{
|
||||
type: 'input',
|
||||
field: 'prop',
|
||||
span: 10,
|
||||
props: {
|
||||
placeholder: t('project.node.prop_tips'),
|
||||
maxLength: 256
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.prop_tips'))
|
||||
}
|
||||
|
||||
const sameItems = model.localParams.filter(
|
||||
(item: { prop: string }) => item.prop === value
|
||||
)
|
||||
|
||||
if (sameItems.length > 1) {
|
||||
return new Error(t('project.node.prop_repeat'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'value',
|
||||
span: 10,
|
||||
props: {
|
||||
placeholder: t('project.node.value_tips'),
|
||||
maxLength: 256
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
useChunjunDeployMode(24),
|
||||
{
|
||||
type: 'input',
|
||||
field: 'others',
|
||||
name: t('project.node.option_parameters'),
|
||||
props: {
|
||||
type: 'textarea',
|
||||
placeholder: t('project.node.option_parameters_tips')
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useTaskNodeStore } from '@/store/project/task-node'
|
||||
import { useRelationCustomParams, useTimeoutAlarm } from '.'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useConditions(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
const taskStore = useTaskNodeStore()
|
||||
|
||||
const preTaskOptions = taskStore.preTaskOptions.filter((option) =>
|
||||
taskStore.preTasks.includes(Number(option.value))
|
||||
)
|
||||
const stateOptions = [
|
||||
{ label: t('project.node.success'), value: 'success' },
|
||||
{ label: t('project.node.failed'), value: 'failed' }
|
||||
]
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'select',
|
||||
field: 'successNode',
|
||||
name: t('project.node.state'),
|
||||
span: 12,
|
||||
props: {
|
||||
disabled: true
|
||||
},
|
||||
options: stateOptions
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'successBranch',
|
||||
name: t('project.node.branch_flow'),
|
||||
span: 12,
|
||||
props: {
|
||||
clearable: true
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
validator: (unuse, value) => {
|
||||
if (value && value === model.failedBranch) {
|
||||
return new Error(t('project.node.branch_tips'))
|
||||
}
|
||||
}
|
||||
},
|
||||
options: taskStore.getPostTaskOptions
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'failedNode',
|
||||
name: t('project.node.state'),
|
||||
span: 12,
|
||||
props: {
|
||||
disabled: true
|
||||
},
|
||||
options: stateOptions
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'failedBranch',
|
||||
name: t('project.node.branch_flow'),
|
||||
span: 12,
|
||||
props: {
|
||||
clearable: true
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
validator: (unuse, value) => {
|
||||
if (value && value === model.successBranch) {
|
||||
return new Error(t('project.node.branch_tips'))
|
||||
}
|
||||
}
|
||||
},
|
||||
options: taskStore.getPostTaskOptions
|
||||
},
|
||||
...useTimeoutAlarm(model),
|
||||
...useRelationCustomParams({
|
||||
model,
|
||||
children: {
|
||||
type: 'custom-parameters',
|
||||
field: 'dependItemList',
|
||||
span: 18,
|
||||
children: [
|
||||
{
|
||||
type: 'select',
|
||||
field: 'depTaskCode',
|
||||
span: 10,
|
||||
options: preTaskOptions
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'status',
|
||||
span: 10,
|
||||
options: [
|
||||
{
|
||||
value: 'SUCCESS',
|
||||
label: t('project.node.success')
|
||||
},
|
||||
{
|
||||
value: 'FAILURE',
|
||||
label: t('project.node.failed')
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
childrenField: 'dependItemList',
|
||||
name: 'add_pre_task_check_condition'
|
||||
})
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useCustomLabels({
|
||||
model,
|
||||
field,
|
||||
name = 'custom_labels',
|
||||
span = 24
|
||||
}: {
|
||||
model: { [field: string]: any }
|
||||
field: string
|
||||
name?: string
|
||||
span?: Ref | number
|
||||
}): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'custom-parameters',
|
||||
field: field,
|
||||
name: t(`project.node.${name}`),
|
||||
class: 'btn-custom-parameters',
|
||||
span,
|
||||
children: [
|
||||
{
|
||||
type: 'input',
|
||||
field: 'label',
|
||||
span: 8,
|
||||
class: 'customized-label-name',
|
||||
props: {
|
||||
placeholder: t('project.node.label_name_tips'),
|
||||
maxLength: 256
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.label_name_tips'))
|
||||
}
|
||||
|
||||
const sameItems = model[field].filter(
|
||||
(item: { label: string }) => item.label === value
|
||||
)
|
||||
|
||||
if (sameItems.length > 1) {
|
||||
return new Error(t('project.node.label_repeat'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'value',
|
||||
span: 14,
|
||||
class: 'customized-label-value',
|
||||
props: {
|
||||
placeholder: t('project.node.label_value_tips'),
|
||||
maxLength: 256
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useCustomParams({
|
||||
model,
|
||||
field,
|
||||
isSimple,
|
||||
name = 'custom_parameters',
|
||||
span = 24
|
||||
}: {
|
||||
model: { [field: string]: any }
|
||||
field: string
|
||||
isSimple: boolean
|
||||
name?: string
|
||||
span?: Ref | number
|
||||
}): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'custom-parameters',
|
||||
field: field,
|
||||
name: t(`project.node.${name}`),
|
||||
class: 'btn-custom-parameters',
|
||||
span,
|
||||
children: [
|
||||
{
|
||||
type: 'input',
|
||||
field: 'prop',
|
||||
span: 6,
|
||||
class: 'input-param-key',
|
||||
props: {
|
||||
placeholder: t('project.node.prop_tips'),
|
||||
maxLength: 256
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.prop_tips'))
|
||||
}
|
||||
|
||||
const sameItems = model[field].filter(
|
||||
(item: { prop: string }) => item.prop === value
|
||||
)
|
||||
|
||||
if (sameItems.length > 1) {
|
||||
return new Error(t('project.node.prop_repeat'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'direct',
|
||||
span: 4,
|
||||
options: DIRECT_LIST,
|
||||
value: 'IN',
|
||||
props: {
|
||||
disabled: isSimple
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'type',
|
||||
span: 6,
|
||||
options: TYPE_LIST,
|
||||
value: 'VARCHAR',
|
||||
props: {
|
||||
disabled: isSimple
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'value',
|
||||
span: 6,
|
||||
class: 'input-param-value',
|
||||
props: {
|
||||
placeholder: t('project.node.value_tips'),
|
||||
maxLength: 256
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const TYPE_LIST = [
|
||||
{
|
||||
value: 'VARCHAR',
|
||||
label: 'VARCHAR'
|
||||
},
|
||||
{
|
||||
value: 'INTEGER',
|
||||
label: 'INTEGER'
|
||||
},
|
||||
{
|
||||
value: 'LONG',
|
||||
label: 'LONG'
|
||||
},
|
||||
{
|
||||
value: 'FLOAT',
|
||||
label: 'FLOAT'
|
||||
},
|
||||
{
|
||||
value: 'DOUBLE',
|
||||
label: 'DOUBLE'
|
||||
},
|
||||
{
|
||||
value: 'DATE',
|
||||
label: 'DATE'
|
||||
},
|
||||
{
|
||||
value: 'TIME',
|
||||
label: 'TIME'
|
||||
},
|
||||
{
|
||||
value: 'TIMESTAMP',
|
||||
label: 'TIMESTAMP'
|
||||
},
|
||||
{
|
||||
value: 'BOOLEAN',
|
||||
label: 'BOOLEAN'
|
||||
},
|
||||
{
|
||||
value: 'LIST',
|
||||
label: 'LIST'
|
||||
},
|
||||
{
|
||||
value: 'FILE',
|
||||
label: 'FILE'
|
||||
}
|
||||
]
|
||||
|
||||
export const DIRECT_LIST = [
|
||||
{
|
||||
value: 'IN',
|
||||
label: 'IN'
|
||||
},
|
||||
{
|
||||
value: 'OUT',
|
||||
label: 'OUT'
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
queryDataFactoryFactories,
|
||||
queryDataFactoryPipelines,
|
||||
queryDataFactoryResourceGroups
|
||||
} from '@/service/modules/azure'
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useCustomParams } from '.'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useDataFactory(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
const factoryLoading = ref(false)
|
||||
const resourceGroupLoading = ref(false)
|
||||
const pipelineLoading = ref(false)
|
||||
|
||||
const factoryOptions = ref([] as { label: string; value: number }[])
|
||||
const resourceGroupOptions = ref([] as { label: string; value: number }[])
|
||||
const pipelineOptions = ref([] as { label: string; value: number }[])
|
||||
|
||||
const getFactoryOptions = async () => {
|
||||
if (factoryLoading.value) return
|
||||
factoryLoading.value = true
|
||||
const factories = await queryDataFactoryFactories()
|
||||
factoryOptions.value = factories.map((factory: string) => ({
|
||||
label: factory,
|
||||
value: factory
|
||||
}))
|
||||
factoryLoading.value = false
|
||||
}
|
||||
|
||||
const getResourceGroupName = async () => {
|
||||
if (resourceGroupLoading.value) return
|
||||
resourceGroupLoading.value = true
|
||||
const groupNames = await queryDataFactoryResourceGroups()
|
||||
resourceGroupOptions.value = groupNames.map((groupName: string) => ({
|
||||
label: groupName,
|
||||
value: groupName
|
||||
}))
|
||||
resourceGroupLoading.value = false
|
||||
}
|
||||
|
||||
const getPipelineName = async (
|
||||
factoryName: string,
|
||||
resourceGroupName: string
|
||||
) => {
|
||||
if (pipelineLoading.value) return
|
||||
pipelineLoading.value = true
|
||||
const pipelineNames = await queryDataFactoryPipelines({
|
||||
factoryName,
|
||||
resourceGroupName
|
||||
})
|
||||
pipelineOptions.value = pipelineNames.map((pipelineName: string) => ({
|
||||
label: pipelineName,
|
||||
value: pipelineName
|
||||
}))
|
||||
pipelineLoading.value = false
|
||||
}
|
||||
|
||||
const onChange = () => {
|
||||
model['pipelineName'] = ''
|
||||
if (model['factoryName'] && model['resourceGroupName']) {
|
||||
getPipelineName(model['factoryName'], model['resourceGroupName'])
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => model['pipelineName'],
|
||||
() => {
|
||||
if (model['pipelineName'] && pipelineOptions.value.length === 0) {
|
||||
getPipelineName(model['factoryName'], model['resourceGroupName'])
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
getFactoryOptions()
|
||||
getResourceGroupName()
|
||||
})
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'select',
|
||||
field: 'factoryName',
|
||||
span: 24,
|
||||
name: t('project.node.factory_name'),
|
||||
options: factoryOptions,
|
||||
props: {
|
||||
'on-update:value': onChange,
|
||||
loading: factoryLoading
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'trigger'],
|
||||
required: true,
|
||||
message: t('project.node.factory_tips')
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'resourceGroupName',
|
||||
span: 24,
|
||||
name: t('project.node.resource_group_name'),
|
||||
options: resourceGroupOptions,
|
||||
props: {
|
||||
'on-update:value': onChange,
|
||||
loading: resourceGroupLoading
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'trigger'],
|
||||
required: true,
|
||||
message: t('project.node.resource_group_tips')
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'pipelineName',
|
||||
span: 24,
|
||||
name: t('project.node.pipeline_name'),
|
||||
options: pipelineOptions,
|
||||
props: {
|
||||
loading: pipelineLoading
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'trigger'],
|
||||
required: true,
|
||||
message: t('project.node.pipeline_tips')
|
||||
}
|
||||
},
|
||||
...useCustomParams({
|
||||
model,
|
||||
field: 'localParams',
|
||||
isSimple: true
|
||||
})
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ref, onMounted, nextTick, Ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { queryDataSourceList } from '@/service/modules/data-source'
|
||||
import { indexOf, find } from 'lodash'
|
||||
import type { IJsonItem } from '../types'
|
||||
import type { TypeReq } from '@/service/modules/data-source/types'
|
||||
|
||||
export function useDatasource(
|
||||
model: { [field: string]: any },
|
||||
params: {
|
||||
supportedDatasourceType?: string[]
|
||||
typeField?: string
|
||||
sourceField?: string
|
||||
span?: Ref | number
|
||||
testFlag?: Ref | number
|
||||
} = {}
|
||||
): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
const options = ref([] as { label: string; value: string }[])
|
||||
const datasourceOptions = ref([] as { label: string; value: number }[])
|
||||
|
||||
const datasourceTypes = [
|
||||
{
|
||||
id: 0,
|
||||
code: 'MYSQL',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
code: 'POSTGRESQL',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
code: 'HIVE',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
code: 'SPARK',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
code: 'CLICKHOUSE',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
code: 'ORACLE',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
code: 'SQLSERVER',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
code: 'DB2',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
code: 'PRESTO',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
code: 'REDSHIFT',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
code: 'ATHENA',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
code: 'TRINO',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
code: 'STARROCKS',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
code: 'AZURESQL',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
code: 'DAMENG',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
code: 'OCEANBASE',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
code: 'SSH',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
code: 'KYUUBI',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 19,
|
||||
code: 'DATABEND',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 21,
|
||||
code: 'VERTICA',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
code: 'HANA',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
code: 'DORIS',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 24,
|
||||
code: 'ZEPPELIN',
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
id: 25,
|
||||
code: 'SAGEMAKER',
|
||||
disabled: false
|
||||
}
|
||||
]
|
||||
|
||||
const getDatasourceTypes = async () => {
|
||||
options.value = datasourceTypes
|
||||
.filter((item) => {
|
||||
if (item.disabled) {
|
||||
return false
|
||||
}
|
||||
if (params.supportedDatasourceType) {
|
||||
return indexOf(params.supportedDatasourceType, item.code) !== -1
|
||||
}
|
||||
return true
|
||||
})
|
||||
.map((item) => ({ label: item.code, value: item.code }))
|
||||
}
|
||||
|
||||
const refreshOptions = async () => {
|
||||
const parameters = {
|
||||
type: model[params.typeField || 'type'],
|
||||
testFlag: 0
|
||||
} as TypeReq
|
||||
const res = await queryDataSourceList(parameters)
|
||||
datasourceOptions.value = res.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}))
|
||||
const sourceField = params.sourceField || 'datasource'
|
||||
if (!res.length && model[sourceField]) model[sourceField] = null
|
||||
if (res.length && model[sourceField]) {
|
||||
const item = find(res, { id: model[sourceField] })
|
||||
if (!item) {
|
||||
model[sourceField] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onChange = () => {
|
||||
refreshOptions()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
getDatasourceTypes()
|
||||
await nextTick()
|
||||
refreshOptions()
|
||||
})
|
||||
return [
|
||||
{
|
||||
type: 'select',
|
||||
field: params.typeField || 'type',
|
||||
span: params.span || 12,
|
||||
name: t('project.node.datasource_type'),
|
||||
props: {
|
||||
'on-update:value': onChange
|
||||
},
|
||||
options: options,
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: params.sourceField || 'datasource',
|
||||
span: params.span || 12,
|
||||
name: t('project.node.datasource_instances'),
|
||||
options: datasourceOptions,
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(unuse: any, value) {
|
||||
if (!value && value !== 0) {
|
||||
return Error(t('project.node.datasource_instances'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { IJsonItem } from '../types'
|
||||
import { watch, ref } from 'vue'
|
||||
import { useCustomParams } from '.'
|
||||
|
||||
export function useDatasync(model: { [field: string]: any }): IJsonItem[] {
|
||||
const jsonSpan = ref(0)
|
||||
const destinationLocationArnSpan = ref(0)
|
||||
const sourceLocationArnSpan = ref(0)
|
||||
const nameSpan = ref(0)
|
||||
const cloudWatchLogGroupArnSpan = ref(0)
|
||||
|
||||
const resetSpan = () => {
|
||||
jsonSpan.value = model.jsonFormat ? 24 : 0
|
||||
destinationLocationArnSpan.value = model.jsonFormat ? 0 : 24
|
||||
sourceLocationArnSpan.value = model.jsonFormat ? 0 : 24
|
||||
nameSpan.value = model.jsonFormat ? 0 : 24
|
||||
cloudWatchLogGroupArnSpan.value = model.jsonFormat ? 0 : 24
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [model.jsonFormat],
|
||||
() => {
|
||||
resetSpan()
|
||||
}
|
||||
)
|
||||
|
||||
resetSpan()
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'switch',
|
||||
field: 'jsonFormat',
|
||||
name: 'jsonFormat',
|
||||
span: 12
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
field: 'json',
|
||||
name: 'json',
|
||||
span: jsonSpan
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'destinationLocationArn',
|
||||
name: 'destinationLocationArn',
|
||||
span: destinationLocationArnSpan
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'sourceLocationArn',
|
||||
name: 'sourceLocationArn',
|
||||
span: sourceLocationArnSpan
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'name',
|
||||
name: 'name',
|
||||
span: nameSpan
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'cloudWatchLogGroupArn',
|
||||
name: 'cloudWatchLogGroupArn',
|
||||
span: cloudWatchLogGroupArnSpan
|
||||
},
|
||||
...useCustomParams({ model, field: 'localParams', isSimple: false })
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useCustomParams, useDatasource, useResources } from '.'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useDataX(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
const jobSpeedByteOptions: any[] = [
|
||||
{
|
||||
label: `0(${t('project.node.unlimited')})`,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: '1KB',
|
||||
value: 1024
|
||||
},
|
||||
{
|
||||
label: '10KB',
|
||||
value: 10240
|
||||
},
|
||||
{
|
||||
label: '50KB',
|
||||
value: 51200
|
||||
},
|
||||
{
|
||||
label: '100KB',
|
||||
value: 102400
|
||||
},
|
||||
{
|
||||
label: '512KB',
|
||||
value: 524288
|
||||
}
|
||||
]
|
||||
const jobSpeedRecordOptions: any[] = [
|
||||
{
|
||||
label: `0(${t('project.node.unlimited')})`,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: '500',
|
||||
value: 500
|
||||
},
|
||||
{
|
||||
label: '1000',
|
||||
value: 1000
|
||||
},
|
||||
{
|
||||
label: '1500',
|
||||
value: 1500
|
||||
},
|
||||
{
|
||||
label: '2000',
|
||||
value: 2000
|
||||
},
|
||||
{
|
||||
label: '2500',
|
||||
value: 2500
|
||||
},
|
||||
{
|
||||
label: '3000',
|
||||
value: 3000
|
||||
}
|
||||
]
|
||||
const memoryLimitOptions = [
|
||||
{
|
||||
label: '1G',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: '2G',
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
label: '3G',
|
||||
value: 3
|
||||
},
|
||||
{
|
||||
label: '4G',
|
||||
value: 4
|
||||
}
|
||||
]
|
||||
|
||||
const sqlEditorSpan = ref(24)
|
||||
const jsonEditorSpan = ref(0)
|
||||
const datasourceSpan = ref(12)
|
||||
const destinationDatasourceSpan = ref(8)
|
||||
const otherStatementSpan = ref(22)
|
||||
const jobSpeedSpan = ref(12)
|
||||
const useResourcesSpan = ref(0)
|
||||
|
||||
const initConstants = () => {
|
||||
if (model.customConfig) {
|
||||
sqlEditorSpan.value = 0
|
||||
jsonEditorSpan.value = 24
|
||||
datasourceSpan.value = 0
|
||||
destinationDatasourceSpan.value = 0
|
||||
otherStatementSpan.value = 0
|
||||
jobSpeedSpan.value = 0
|
||||
useResourcesSpan.value = 24
|
||||
} else {
|
||||
sqlEditorSpan.value = 24
|
||||
jsonEditorSpan.value = 0
|
||||
datasourceSpan.value = 12
|
||||
destinationDatasourceSpan.value = 8
|
||||
otherStatementSpan.value = 22
|
||||
jobSpeedSpan.value = 12
|
||||
useResourcesSpan.value = 0
|
||||
}
|
||||
}
|
||||
const supportedDatasourceType = [
|
||||
'MYSQL',
|
||||
'POSTGRESQL',
|
||||
'ORACLE',
|
||||
'SQLSERVER',
|
||||
'CLICKHOUSE',
|
||||
'DATABEND',
|
||||
'HIVE',
|
||||
'PRESTO'
|
||||
]
|
||||
onMounted(() => {
|
||||
initConstants()
|
||||
})
|
||||
watch(
|
||||
() => model.customConfig,
|
||||
() => {
|
||||
initConstants()
|
||||
}
|
||||
)
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'switch',
|
||||
field: 'customConfig',
|
||||
name: t('project.node.datax_custom_template')
|
||||
},
|
||||
...useDatasource(model, {
|
||||
typeField: 'dsType',
|
||||
sourceField: 'dataSource',
|
||||
span: datasourceSpan,
|
||||
supportedDatasourceType
|
||||
}),
|
||||
{
|
||||
type: 'editor',
|
||||
field: 'sql',
|
||||
name: t('project.node.sql_statement'),
|
||||
span: sqlEditorSpan,
|
||||
validate: {
|
||||
trigger: ['input', 'trigger'],
|
||||
required: true,
|
||||
message: t('project.node.sql_empty_tips')
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
field: 'json',
|
||||
name: t('project.node.datax_json_template'),
|
||||
span: jsonEditorSpan,
|
||||
validate: {
|
||||
trigger: ['input', 'trigger'],
|
||||
required: true,
|
||||
message: t('project.node.sql_empty_tips')
|
||||
}
|
||||
},
|
||||
useResources(useResourcesSpan),
|
||||
...useDatasource(model, {
|
||||
typeField: 'dtType',
|
||||
sourceField: 'dataTarget',
|
||||
span: destinationDatasourceSpan,
|
||||
supportedDatasourceType
|
||||
}),
|
||||
{
|
||||
type: 'input',
|
||||
field: 'targetTable',
|
||||
name: t('project.node.datax_target_table'),
|
||||
span: destinationDatasourceSpan,
|
||||
props: {
|
||||
placeholder: t('project.node.datax_target_table_tips')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'multi-input',
|
||||
field: 'preStatements',
|
||||
name: t('project.node.datax_target_database_pre_sql'),
|
||||
span: otherStatementSpan,
|
||||
props: {
|
||||
placeholder: t('project.node.datax_non_query_sql_tips'),
|
||||
type: 'textarea',
|
||||
autosize: { minRows: 1 }
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'multi-input',
|
||||
field: 'postStatements',
|
||||
name: t('project.node.datax_target_database_post_sql'),
|
||||
span: otherStatementSpan,
|
||||
props: {
|
||||
placeholder: t('project.node.datax_non_query_sql_tips'),
|
||||
type: 'textarea',
|
||||
autosize: { minRows: 1 }
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'jobSpeedByte',
|
||||
name: t('project.node.datax_job_speed_byte'),
|
||||
span: jobSpeedSpan,
|
||||
options: jobSpeedByteOptions,
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'jobSpeedRecord',
|
||||
name: t('project.node.datax_job_speed_record'),
|
||||
span: jobSpeedSpan,
|
||||
options: jobSpeedRecordOptions,
|
||||
value: 1000
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'xms',
|
||||
name: t('project.node.datax_job_runtime_memory_xms'),
|
||||
span: 12,
|
||||
options: memoryLimitOptions,
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'xmx',
|
||||
name: t('project.node.datax_job_runtime_memory_xmx'),
|
||||
span: 12,
|
||||
options: memoryLimitOptions,
|
||||
value: 1
|
||||
},
|
||||
...useCustomParams({ model, field: 'localParams', isSimple: true })
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useDelayTime(model: { [field: string]: any }): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
return {
|
||||
type: 'input-number',
|
||||
field: 'delayTime',
|
||||
name: t('project.node.delay_execution_time'),
|
||||
span: 12,
|
||||
props: {
|
||||
min: 0
|
||||
},
|
||||
slots: {
|
||||
suffix: () => t('project.node.minute')
|
||||
},
|
||||
value: model.delayTime || 0
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { computed, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useDependentTimeout(model: {
|
||||
[field: string]: any
|
||||
}): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
const timeCompleteSpan = computed(() => (model.timeoutShowFlag ? 24 : 0))
|
||||
const timeCompleteEnableSpan = computed(() =>
|
||||
model.timeoutFlag && model.timeoutShowFlag ? 12 : 0
|
||||
)
|
||||
|
||||
const strategyOptions = [
|
||||
{
|
||||
label: t('project.node.timeout_alarm'),
|
||||
value: 'WARN'
|
||||
},
|
||||
{
|
||||
label: t('project.node.timeout_failure'),
|
||||
value: 'FAILED'
|
||||
}
|
||||
]
|
||||
|
||||
watch(
|
||||
() => model.timeoutFlag,
|
||||
(timeoutFlag) => {
|
||||
model.timeoutShowFlag = timeoutFlag
|
||||
}
|
||||
)
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'switch',
|
||||
field: 'timeoutShowFlag',
|
||||
name: t('project.node.timeout_alarm')
|
||||
},
|
||||
{
|
||||
type: 'switch',
|
||||
field: 'timeoutFlag',
|
||||
name: t('project.node.waiting_dependent_complete'),
|
||||
props: {
|
||||
'on-update:value': (value: boolean) => {
|
||||
if (value) {
|
||||
if (!model.timeoutNotifyStrategy.length) {
|
||||
model.timeoutNotifyStrategy = ['WARN']
|
||||
}
|
||||
if (!model.timeout) {
|
||||
model.timeout = 30
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
span: timeCompleteSpan
|
||||
},
|
||||
{
|
||||
type: 'input-number',
|
||||
field: 'timeout',
|
||||
name: t('project.node.timeout_period'),
|
||||
span: timeCompleteEnableSpan,
|
||||
props: {
|
||||
max: Math.pow(9, 10) - 1
|
||||
},
|
||||
slots: {
|
||||
suffix: () => t('project.node.minute')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input'],
|
||||
validator(validate: any, value: number) {
|
||||
if (model.timeoutFlag && !/^[1-9]\d*$/.test(String(value))) {
|
||||
return new Error(t('project.node.timeout_period_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'checkbox',
|
||||
field: 'timeoutNotifyStrategy',
|
||||
name: t('project.node.timeout_strategy'),
|
||||
options: strategyOptions,
|
||||
span: timeCompleteEnableSpan,
|
||||
validate: {
|
||||
trigger: ['input'],
|
||||
validator(validate: any, value: []) {
|
||||
if (model.waitCompleteTimeoutEnable && !value.length) {
|
||||
return new Error(t('project.node.timeout_strategy_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,550 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ref, onMounted, watch, h, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { NEllipsis, NIcon } from 'naive-ui'
|
||||
import { useRelationCustomParams, useDependentTimeout } from '.'
|
||||
import { useTaskNodeStore } from '@/store/project/task-node'
|
||||
import { queryAllProjectListForDependent } from '@/service/modules/projects'
|
||||
import { tasksState } from '@/common/common'
|
||||
import {
|
||||
queryProcessDefinitionList,
|
||||
getTasksByDefinitionList
|
||||
} from '@/service/modules/process-definition'
|
||||
import { Router, useRouter } from 'vue-router'
|
||||
import type {
|
||||
IJsonItem,
|
||||
IDependentItem,
|
||||
IDependentItemOptions,
|
||||
IDependTaskOptions,
|
||||
IDependTask,
|
||||
ITaskState,
|
||||
IDateType
|
||||
} from '../types'
|
||||
import { IRenderOption } from '../types'
|
||||
|
||||
export function useDependent(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
const router: Router = useRouter()
|
||||
const nodeStore = useTaskNodeStore()
|
||||
|
||||
const dependentFailurePolicyOptions = computed(() => {
|
||||
return [
|
||||
{
|
||||
label: t('project.node.dependent_failure_policy_failure'),
|
||||
value: 'DEPENDENT_FAILURE_FAILURE'
|
||||
},
|
||||
{
|
||||
label: t('project.node.dependent_failure_policy_waiting'),
|
||||
value: 'DEPENDENT_FAILURE_WAITING'
|
||||
}
|
||||
]
|
||||
})
|
||||
const failureWaitingTimeSpan = computed(() =>
|
||||
model.failurePolicy === 'DEPENDENT_FAILURE_WAITING' ? 12 : 0
|
||||
)
|
||||
const dependentResult = nodeStore.getDependentResult
|
||||
const TasksStateConfig = tasksState(t)
|
||||
const projectList = ref([] as IRenderOption[])
|
||||
const processCache = {} as {
|
||||
[key: number]: IRenderOption[]
|
||||
}
|
||||
const taskCache = {} as {
|
||||
[key: number]: IRenderOption[]
|
||||
}
|
||||
const selectOptions = ref([] as IDependTaskOptions[])
|
||||
|
||||
const DependentTypeOptions = [
|
||||
{
|
||||
value: 'DEPENDENT_ON_WORKFLOW',
|
||||
label: t('project.node.dependent_on_workflow')
|
||||
},
|
||||
{
|
||||
value: 'DEPENDENT_ON_TASK',
|
||||
label: t('project.node.dependent_on_task')
|
||||
}
|
||||
]
|
||||
|
||||
const CYCLE_LIST = [
|
||||
{
|
||||
value: 'month',
|
||||
label: t('project.node.month')
|
||||
},
|
||||
{
|
||||
value: 'week',
|
||||
label: t('project.node.week')
|
||||
},
|
||||
{
|
||||
value: 'day',
|
||||
label: t('project.node.day')
|
||||
},
|
||||
{
|
||||
value: 'hour',
|
||||
label: t('project.node.hour')
|
||||
}
|
||||
]
|
||||
const DATE_LIST = {
|
||||
hour: [
|
||||
{
|
||||
value: 'currentHour',
|
||||
label: t('project.node.current_hour')
|
||||
},
|
||||
{
|
||||
value: 'last1Hour',
|
||||
label: t('project.node.last_1_hour')
|
||||
},
|
||||
{
|
||||
value: 'last2Hours',
|
||||
label: t('project.node.last_2_hour')
|
||||
},
|
||||
{
|
||||
value: 'last3Hours',
|
||||
label: t('project.node.last_3_hour')
|
||||
},
|
||||
{
|
||||
value: 'last24Hours',
|
||||
label: t('project.node.last_24_hour')
|
||||
}
|
||||
],
|
||||
day: [
|
||||
{
|
||||
value: 'today',
|
||||
label: t('project.node.today')
|
||||
},
|
||||
{
|
||||
value: 'last1Days',
|
||||
label: t('project.node.last_1_days')
|
||||
},
|
||||
{
|
||||
value: 'last2Days',
|
||||
label: t('project.node.last_2_days')
|
||||
},
|
||||
{
|
||||
value: 'last3Days',
|
||||
label: t('project.node.last_3_days')
|
||||
},
|
||||
{
|
||||
value: 'last7Days',
|
||||
label: t('project.node.last_7_days')
|
||||
}
|
||||
],
|
||||
week: [
|
||||
{
|
||||
value: 'thisWeek',
|
||||
label: t('project.node.this_week')
|
||||
},
|
||||
{
|
||||
value: 'lastWeek',
|
||||
label: t('project.node.last_week')
|
||||
},
|
||||
{
|
||||
value: 'lastMonday',
|
||||
label: t('project.node.last_monday')
|
||||
},
|
||||
{
|
||||
value: 'lastTuesday',
|
||||
label: t('project.node.last_tuesday')
|
||||
},
|
||||
{
|
||||
value: 'lastWednesday',
|
||||
label: t('project.node.last_wednesday')
|
||||
},
|
||||
{
|
||||
value: 'lastThursday',
|
||||
label: t('project.node.last_thursday')
|
||||
},
|
||||
{
|
||||
value: 'lastFriday',
|
||||
label: t('project.node.last_friday')
|
||||
},
|
||||
{
|
||||
value: 'lastSaturday',
|
||||
label: t('project.node.last_saturday')
|
||||
},
|
||||
{
|
||||
value: 'lastSunday',
|
||||
label: t('project.node.last_sunday')
|
||||
}
|
||||
],
|
||||
month: [
|
||||
{
|
||||
value: 'thisMonth',
|
||||
label: t('project.node.this_month')
|
||||
},
|
||||
{
|
||||
value: 'thisMonthBegin',
|
||||
label: t('project.node.this_month_begin')
|
||||
},
|
||||
{
|
||||
value: 'lastMonth',
|
||||
label: t('project.node.last_month')
|
||||
},
|
||||
{
|
||||
value: 'lastMonthBegin',
|
||||
label: t('project.node.last_month_begin')
|
||||
},
|
||||
{
|
||||
value: 'lastMonthEnd',
|
||||
label: t('project.node.last_month_end')
|
||||
}
|
||||
]
|
||||
} as { [key in IDateType]: { value: string; label: string }[] }
|
||||
|
||||
const getProjectList = async () => {
|
||||
const result = await queryAllProjectListForDependent()
|
||||
projectList.value = result.map((item: { code: number; name: string }) => ({
|
||||
value: item.code,
|
||||
label: () => h(NEllipsis, null, item.name),
|
||||
filterLabel: item.name
|
||||
}))
|
||||
return projectList
|
||||
}
|
||||
const getProcessList = async (code: number) => {
|
||||
if (processCache[code]) {
|
||||
return processCache[code]
|
||||
}
|
||||
const result = await queryProcessDefinitionList(code)
|
||||
const processList = result.map((item: { code: number; name: string }) => ({
|
||||
value: item.code,
|
||||
label: () => h(NEllipsis, null, item.name),
|
||||
filterLabel: item.name
|
||||
}))
|
||||
processCache[code] = processList
|
||||
|
||||
return processList
|
||||
}
|
||||
|
||||
const getTaskList = async (code: number, processCode: number) => {
|
||||
if (taskCache[processCode]) {
|
||||
return taskCache[processCode]
|
||||
}
|
||||
const result = await getTasksByDefinitionList(code, processCode)
|
||||
const taskList = result.map((item: { code: number; name: string }) => ({
|
||||
value: item.code,
|
||||
label: () => h(NEllipsis, null, item.name),
|
||||
filterLabel: item.name
|
||||
}))
|
||||
taskList.unshift({
|
||||
value: -1,
|
||||
label: 'ALL',
|
||||
filterLabel: 'ALL'
|
||||
})
|
||||
taskCache[processCode] = taskList
|
||||
return taskList
|
||||
}
|
||||
|
||||
const renderState = (item: {
|
||||
definitionCode: number
|
||||
depTaskCode: number
|
||||
cycle: string
|
||||
dateValue: string
|
||||
}) => {
|
||||
if (!item || router.currentRoute.value.name !== 'workflow-instance-detail')
|
||||
return null
|
||||
const key = `${item.definitionCode}-${item.depTaskCode}-${item.cycle}-${item.dateValue}`
|
||||
const state: ITaskState = dependentResult[key]
|
||||
return h(NIcon, { size: 24, color: TasksStateConfig[state]?.color }, () =>
|
||||
h(TasksStateConfig[state]?.icon)
|
||||
)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getProjectList()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => model.dependTaskList,
|
||||
(value) => {
|
||||
selectOptions.value = []
|
||||
value.forEach((item: IDependTask, taskIndex: number) => {
|
||||
if (!item.dependItemList?.length) return
|
||||
|
||||
const itemListOptions = ref([] as IDependentItemOptions[])
|
||||
item.dependItemList?.forEach(
|
||||
async (dependItem: IDependentItem, itemIndex: number) => {
|
||||
itemListOptions.value[itemIndex] = {}
|
||||
|
||||
if (!dependItem.dependentType) {
|
||||
if (dependItem.depTaskCode == 0)
|
||||
dependItem.dependentType = 'DEPENDENT_ON_WORKFLOW'
|
||||
else dependItem.dependentType = 'DEPENDENT_ON_TASK'
|
||||
}
|
||||
if (dependItem.projectCode) {
|
||||
itemListOptions.value[itemIndex].definitionCodeOptions =
|
||||
await getProcessList(dependItem.projectCode)
|
||||
}
|
||||
if (dependItem.projectCode && dependItem.definitionCode) {
|
||||
itemListOptions.value[itemIndex].depTaskCodeOptions =
|
||||
await getTaskList(
|
||||
dependItem.projectCode,
|
||||
dependItem.definitionCode
|
||||
)
|
||||
}
|
||||
if (dependItem.cycle) {
|
||||
itemListOptions.value[itemIndex].dateOptions =
|
||||
DATE_LIST[dependItem.cycle]
|
||||
}
|
||||
}
|
||||
)
|
||||
selectOptions.value[taskIndex] = {} as IDependTaskOptions
|
||||
selectOptions.value[taskIndex].dependItemList = itemListOptions.value
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
return [
|
||||
...useDependentTimeout(model),
|
||||
...useRelationCustomParams({
|
||||
model,
|
||||
children: (i = 0) => ({
|
||||
type: 'custom-parameters',
|
||||
field: 'dependItemList',
|
||||
span: 18,
|
||||
children: [
|
||||
(j = 0) => ({
|
||||
type: 'select',
|
||||
field: 'dependentType',
|
||||
name: t('project.node.dependent_type'),
|
||||
span: 24,
|
||||
props: {
|
||||
onUpdateValue: (dependentType: string) => {
|
||||
const item = model.dependTaskList[i].dependItemList[j]
|
||||
if (item.definitionCode)
|
||||
item.depTaskCode =
|
||||
dependentType === 'DEPENDENT_ON_WORKFLOW' ? 0 : -1
|
||||
}
|
||||
},
|
||||
options: DependentTypeOptions,
|
||||
value: 'DEPENDENT_ON_WORKFLOW'
|
||||
}),
|
||||
(j = 0) => ({
|
||||
type: 'select',
|
||||
field: 'projectCode',
|
||||
name: t('project.node.project_name'),
|
||||
span: 24,
|
||||
props: {
|
||||
filterable: true,
|
||||
filter: (query: string, option: IRenderOption) => {
|
||||
return option.filterLabel
|
||||
.toLowerCase()
|
||||
.includes(query.toLowerCase())
|
||||
},
|
||||
onUpdateValue: async (projectCode: number) => {
|
||||
const item = model.dependTaskList[i].dependItemList[j]
|
||||
const options = selectOptions?.value[i] || {}
|
||||
const itemListOptions = options?.dependItemList || []
|
||||
const itemOptions = {} as IDependentItemOptions
|
||||
itemOptions.definitionCodeOptions = await getProcessList(
|
||||
projectCode
|
||||
)
|
||||
itemListOptions[j] = itemOptions
|
||||
options.dependItemList = itemListOptions
|
||||
selectOptions.value[i] = options
|
||||
item.depTaskCode = null
|
||||
item.definitionCode = null
|
||||
item.parameterPassing = false
|
||||
}
|
||||
},
|
||||
options: projectList,
|
||||
path: `dependTaskList.${i}.dependItemList.${j}.projectCode`,
|
||||
rule: {
|
||||
required: true,
|
||||
trigger: ['input', 'blur'],
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return Error(t('project.node.project_name_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
(j = 0) => ({
|
||||
type: 'select',
|
||||
field: 'definitionCode',
|
||||
span: 24,
|
||||
name: t('project.node.process_name'),
|
||||
props: {
|
||||
filterable: true,
|
||||
filter: (query: string, option: IRenderOption) => {
|
||||
return option.filterLabel
|
||||
.toLowerCase()
|
||||
.includes(query.toLowerCase())
|
||||
},
|
||||
onUpdateValue: async (processCode: number) => {
|
||||
const item = model.dependTaskList[i].dependItemList[j]
|
||||
selectOptions.value[i].dependItemList[j].depTaskCodeOptions =
|
||||
await getTaskList(item.projectCode, processCode)
|
||||
item.depTaskCode =
|
||||
item.dependentType === 'DEPENDENT_ON_WORKFLOW' ? 0 : -1
|
||||
}
|
||||
},
|
||||
options:
|
||||
selectOptions.value[i]?.dependItemList[j]
|
||||
?.definitionCodeOptions || [],
|
||||
path: `dependTaskList.${i}.dependItemList.${j}.definitionCode`,
|
||||
rule: {
|
||||
required: true,
|
||||
trigger: ['input', 'blur'],
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return Error(t('project.node.process_name_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
(j = 0) => ({
|
||||
type: 'select',
|
||||
field: 'depTaskCode',
|
||||
span: computed(() => {
|
||||
const item = model.dependTaskList[i].dependItemList[j]
|
||||
return item.dependentType === 'DEPENDENT_ON_WORKFLOW' ? 0 : 24
|
||||
}),
|
||||
name: t('project.node.task_name'),
|
||||
props: {
|
||||
filterable: true,
|
||||
filter: (query: string, option: IRenderOption) => {
|
||||
return option.filterLabel
|
||||
.toLowerCase()
|
||||
.includes(query.toLowerCase())
|
||||
}
|
||||
},
|
||||
options:
|
||||
selectOptions.value[i]?.dependItemList[j]?.depTaskCodeOptions ||
|
||||
[],
|
||||
path: `dependTaskList.${i}.dependItemList.${j}.depTaskCode`,
|
||||
rule: {
|
||||
required: true,
|
||||
trigger: ['input', 'blur'],
|
||||
validator(validate: any, value: number) {
|
||||
if (!value && value !== 0) {
|
||||
return Error(t('project.node.task_name_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
(j = 0) => ({
|
||||
type: 'select',
|
||||
field: 'cycle',
|
||||
span: 10,
|
||||
name: t('project.node.cycle_time'),
|
||||
props: {
|
||||
onUpdateValue: (value: IDateType) => {
|
||||
selectOptions.value[i].dependItemList[j].dateOptions =
|
||||
DATE_LIST[value]
|
||||
model.dependTaskList[i].dependItemList[j].dateValue = null
|
||||
}
|
||||
},
|
||||
options: CYCLE_LIST,
|
||||
path: `dependTaskList.${i}.dependItemList.${j}.cycle`,
|
||||
rule: {
|
||||
required: true,
|
||||
trigger: ['input', 'blur'],
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return Error(t('project.node.cycle_time_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
(j = 0) => ({
|
||||
type: 'select',
|
||||
field: 'dateValue',
|
||||
span: 10,
|
||||
name: ' ',
|
||||
options:
|
||||
selectOptions.value[i]?.dependItemList[j]?.dateOptions || [],
|
||||
path: `dependTaskList.${i}.dependItemList.${j}.dateValue`,
|
||||
rule: {
|
||||
trigger: ['input', 'blur'],
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return Error(t('project.node.date_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
(j = 0) => ({
|
||||
type: 'switch',
|
||||
field: 'parameterPassing',
|
||||
span: 20,
|
||||
name: t('project.node.dependent_task_parameter_passing'),
|
||||
path: `dependTaskList.${i}.dependItemList.${j}.parameterPassing`
|
||||
}),
|
||||
(j = 0) => ({
|
||||
type: 'custom',
|
||||
field: 'state',
|
||||
span: 2,
|
||||
name: ' ',
|
||||
widget: renderState(model.dependTaskList[i]?.dependItemList[j])
|
||||
})
|
||||
]
|
||||
}),
|
||||
childrenField: 'dependItemList',
|
||||
name: 'add_dependency'
|
||||
}),
|
||||
{
|
||||
type: 'input-number',
|
||||
field: 'checkInterval',
|
||||
name: t('project.node.check_interval'),
|
||||
span: 12,
|
||||
props: {
|
||||
max: Math.pow(9, 10) - 1
|
||||
},
|
||||
slots: {
|
||||
suffix: () => t('project.node.second')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input'],
|
||||
validator(validate: any, value: number) {
|
||||
if (!value && !/^[1-9]\d*$/.test(String(value))) {
|
||||
return new Error(t('project.node.check_interval_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'radio',
|
||||
field: 'failurePolicy',
|
||||
name: t('project.node.dependent_failure_policy'),
|
||||
options: dependentFailurePolicyOptions,
|
||||
span: 24
|
||||
},
|
||||
{
|
||||
type: 'input-number',
|
||||
field: 'failureWaitingTime',
|
||||
name: t('project.node.dependent_failure_waiting_time'),
|
||||
span: failureWaitingTimeSpan,
|
||||
props: {
|
||||
max: Math.pow(9, 10) - 1
|
||||
},
|
||||
slots: {
|
||||
suffix: () => t('project.node.minute')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input'],
|
||||
required: true,
|
||||
validator(validate: any, value: number) {
|
||||
if (model.timeoutFlag && !/^[1-9]\d*$/.test(String(value))) {
|
||||
return new Error(
|
||||
t('project.node.dependent_failure_waiting_time_tips')
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Ref, ref, watchEffect } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem, IOption } from '../types'
|
||||
|
||||
export function useDeployMode(
|
||||
span: number | Ref<number> = 24,
|
||||
showClient = ref(true),
|
||||
showCluster = ref(true),
|
||||
showLocal = ref(true)
|
||||
): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
const deployModeOptions = ref(DEPLOY_MODES as IOption[])
|
||||
|
||||
watchEffect(() => {
|
||||
deployModeOptions.value = DEPLOY_MODES.filter((option) => {
|
||||
switch (option.value) {
|
||||
case 'cluster':
|
||||
return showCluster.value
|
||||
case 'client':
|
||||
return showClient.value
|
||||
case 'local':
|
||||
return showLocal.value
|
||||
default:
|
||||
return true
|
||||
}
|
||||
})
|
||||
})
|
||||
return {
|
||||
type: 'radio',
|
||||
field: 'deployMode',
|
||||
name: t('project.node.deploy_mode'),
|
||||
options: deployModeOptions,
|
||||
span: span
|
||||
}
|
||||
}
|
||||
|
||||
export const DEPLOY_MODES = [
|
||||
{
|
||||
label: 'cluster',
|
||||
value: 'cluster'
|
||||
},
|
||||
{
|
||||
label: 'client',
|
||||
value: 'client'
|
||||
},
|
||||
{
|
||||
label: 'local',
|
||||
value: 'local'
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useDescription(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
return {
|
||||
type: 'input',
|
||||
field: 'description',
|
||||
name: t('project.node.description'),
|
||||
props: {
|
||||
placeholder: t('project.node.description_tips'),
|
||||
rows: 2,
|
||||
type: 'textarea'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useCustomParams } from '.'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useDinky(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'input',
|
||||
field: 'address',
|
||||
name: t('project.node.dinky_address'),
|
||||
props: {
|
||||
placeholder: t('project.node.dinky_address_tips')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(_validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.dinky_address_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'taskId',
|
||||
name: t('project.node.dinky_task_id'),
|
||||
props: {
|
||||
placeholder: t('project.node.dinky_task_id_tips')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(_validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.dinky_task_id_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'switch',
|
||||
field: 'online',
|
||||
name: t('project.node.dinky_online')
|
||||
},
|
||||
...useCustomParams({ model, field: 'localParams', isSimple: false })
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { IJsonItem } from '../types'
|
||||
import { watch, ref } from 'vue'
|
||||
import { useCustomParams, useResources } from '.'
|
||||
|
||||
export function useDms(model: { [field: string]: any }): IJsonItem[] {
|
||||
const jsonDataSpan = ref(0)
|
||||
const replicationTaskArnSpan = ref(0)
|
||||
const replicationTaskIdentifierSpan = ref(0)
|
||||
const sourceEndpointArnSpan = ref(0)
|
||||
const targetEndpointArnSpan = ref(0)
|
||||
const replicationInstanceArnSpan = ref(0)
|
||||
const migrationTypeSpan = ref(0)
|
||||
const tableMappingsSpan = ref(0)
|
||||
|
||||
const setFlag = () => {
|
||||
model.isCreateAndNotJson =
|
||||
!model.isRestartTask && !model.isJsonFormat ? true : false
|
||||
model.isRestartAndNotJson =
|
||||
model.isRestartTask && !model.isJsonFormat ? true : false
|
||||
}
|
||||
|
||||
const resetSpan = () => {
|
||||
jsonDataSpan.value = model.isJsonFormat ? 24 : 0
|
||||
replicationTaskArnSpan.value = model.isRestartAndNotJson ? 24 : 0
|
||||
migrationTypeSpan.value = model.isCreateAndNotJson ? 24 : 0
|
||||
sourceEndpointArnSpan.value = model.isCreateAndNotJson ? 24 : 0
|
||||
replicationTaskIdentifierSpan.value = model.isCreateAndNotJson ? 24 : 0
|
||||
targetEndpointArnSpan.value = model.isCreateAndNotJson ? 24 : 0
|
||||
replicationInstanceArnSpan.value = model.isCreateAndNotJson ? 24 : 0
|
||||
tableMappingsSpan.value = model.isCreateAndNotJson ? 24 : 0
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [model.isRestartTask, model.isJsonFormat],
|
||||
() => {
|
||||
setFlag()
|
||||
resetSpan()
|
||||
}
|
||||
)
|
||||
|
||||
setFlag()
|
||||
resetSpan()
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'switch',
|
||||
field: 'isRestartTask',
|
||||
name: 'isRestartTask',
|
||||
span: 12
|
||||
},
|
||||
{
|
||||
type: 'switch',
|
||||
field: 'isJsonFormat',
|
||||
name: 'isJsonFormat',
|
||||
span: 12
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
field: 'jsonData',
|
||||
name: 'jsonData',
|
||||
span: jsonDataSpan
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
field: 'migrationType',
|
||||
name: 'migrationType',
|
||||
span: migrationTypeSpan,
|
||||
options: MIGRATION_TYPE
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'replicationTaskIdentifier',
|
||||
name: 'replicationTaskIdentifier',
|
||||
span: replicationTaskIdentifierSpan
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'replicationInstanceArn',
|
||||
name: 'replicationInstanceArn',
|
||||
span: replicationInstanceArnSpan
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'sourceEndpointArn',
|
||||
name: 'sourceEndpointArn',
|
||||
span: sourceEndpointArnSpan
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'targetEndpointArn',
|
||||
name: 'targetEndpointArn',
|
||||
span: targetEndpointArnSpan
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
field: 'tableMappings',
|
||||
name: 'tableMappings',
|
||||
span: tableMappingsSpan
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'replicationTaskArn',
|
||||
name: 'replicationTaskArn',
|
||||
span: replicationTaskArnSpan
|
||||
},
|
||||
useResources(),
|
||||
...useCustomParams({ model, field: 'localParams', isSimple: false })
|
||||
]
|
||||
}
|
||||
|
||||
export const MIGRATION_TYPE = [
|
||||
{
|
||||
label: 'full-load',
|
||||
value: 'full-load'
|
||||
},
|
||||
{
|
||||
label: 'cdc',
|
||||
value: 'cdc'
|
||||
},
|
||||
{
|
||||
label: 'full-load-and-cdc',
|
||||
value: 'full-load-and-cdc'
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useDriverCores(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
type: 'input-number',
|
||||
field: 'driverCores',
|
||||
name: t('project.node.driver_cores'),
|
||||
span: 12,
|
||||
props: {
|
||||
placeholder: t('project.node.driver_cores_tips'),
|
||||
min: 1
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.driver_cores_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useDriverMemory(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
type: 'input',
|
||||
field: 'driverMemory',
|
||||
name: t('project.node.driver_memory'),
|
||||
span: 12,
|
||||
props: {
|
||||
placeholder: t('project.node.driver_memory_tips')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.driver_memory_tips'))
|
||||
}
|
||||
if (!Number.isInteger(parseInt(value))) {
|
||||
return new Error(
|
||||
t('project.node.driver_memory') +
|
||||
t('project.node.positive_integer_tips')
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
import { watch, ref } from 'vue'
|
||||
|
||||
export const DVC_TASK_TYPE = [
|
||||
{
|
||||
label: 'Upload',
|
||||
value: 'Upload'
|
||||
},
|
||||
{
|
||||
label: 'Download',
|
||||
value: 'Download'
|
||||
},
|
||||
{
|
||||
label: 'Init DVC',
|
||||
value: 'Init DVC'
|
||||
}
|
||||
]
|
||||
|
||||
export function useDvc(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
const dvcLoadSaveDataPathSpan = ref(0)
|
||||
const dvcDataLocationSpan = ref(0)
|
||||
const dvcVersionSpan = ref(0)
|
||||
const dvcMessageSpan = ref(0)
|
||||
const dvcStoreUrlSpan = ref(0)
|
||||
|
||||
const setFlag = () => {
|
||||
model.isUpload = model.dvcTaskType === 'Upload'
|
||||
model.isDownload = model.dvcTaskType === 'Download'
|
||||
model.isInit = model.dvcTaskType === 'Init DVC'
|
||||
}
|
||||
|
||||
const resetData = () => {
|
||||
dvcLoadSaveDataPathSpan.value = model.isUpload || model.isDownload ? 24 : 0
|
||||
dvcDataLocationSpan.value = model.isUpload || model.isDownload ? 24 : 0
|
||||
dvcVersionSpan.value = model.isUpload || model.isDownload ? 24 : 0
|
||||
dvcMessageSpan.value = model.isUpload ? 24 : 0
|
||||
dvcStoreUrlSpan.value = model.isInit ? 24 : 0
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [model.dvcTaskType],
|
||||
() => {
|
||||
setFlag()
|
||||
resetData()
|
||||
}
|
||||
)
|
||||
setFlag()
|
||||
resetData()
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'select',
|
||||
field: 'dvcTaskType',
|
||||
name: t('project.node.dvc_task_type'),
|
||||
span: 12,
|
||||
options: DVC_TASK_TYPE
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'dvcRepository',
|
||||
name: t('project.node.dvc_repository'),
|
||||
span: 24,
|
||||
props: {
|
||||
placeholder: t('project.node.dvc_repository_tips')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
message: t('project.node.dvc_empty_tips')
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'dvcDataLocation',
|
||||
name: t('project.node.dvc_data_location'),
|
||||
props: { placeholder: 'dvcDataLocation' },
|
||||
span: dvcDataLocationSpan,
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if ((model.isUpload || model.isDownload) && !value) {
|
||||
return new Error(t('project.node.dvc_empty_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'dvcLoadSaveDataPath',
|
||||
name: t('project.node.dvc_load_save_data_path'),
|
||||
span: dvcLoadSaveDataPathSpan,
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if ((model.isUpload || model.isDownload) && !value) {
|
||||
return new Error(t('project.node.dvc_empty_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'dvcVersion',
|
||||
name: t('project.node.dvc_version'),
|
||||
span: dvcVersionSpan,
|
||||
props: {
|
||||
placeholder: t('project.node.dvc_version_tips')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if ((model.isUpload || model.isDownload) && !value) {
|
||||
return new Error(t('project.node.dvc_empty_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'dvcMessage',
|
||||
name: t('project.node.dvc_message'),
|
||||
span: dvcMessageSpan,
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (model.isUpload && !value) {
|
||||
return new Error(t('project.node.dvc_empty_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'dvcStoreUrl',
|
||||
name: t('project.node.dvc_store_url'),
|
||||
span: dvcStoreUrlSpan,
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!model.isInit && value) {
|
||||
return new Error(t('project.node.dvc_empty_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { IJsonItem } from '../types'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
export function useDynamic(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'input-number',
|
||||
field: 'maxNumOfSubWorkflowInstances',
|
||||
span: 12,
|
||||
name: t('project.node.max_num_of_sub_workflow_instances'),
|
||||
validate: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input-number',
|
||||
field: 'degreeOfParallelism',
|
||||
span: 12,
|
||||
name: t('project.node.parallelism'),
|
||||
validate: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'custom-parameters',
|
||||
field: 'listParameters',
|
||||
name: t('project.node.params_value'),
|
||||
span: 24,
|
||||
children: [
|
||||
{
|
||||
type: 'input',
|
||||
field: 'name',
|
||||
span: 8,
|
||||
props: {
|
||||
placeholder: t('project.node.dynamic_name_tips'),
|
||||
maxLength: 256
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.dynamic_name_tips'))
|
||||
}
|
||||
|
||||
const sameItems = model['listParameters'].filter(
|
||||
(item: { name: string }) => item.name === value
|
||||
)
|
||||
|
||||
if (sameItems.length > 1) {
|
||||
return new Error(t('project.node.prop_repeat'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'value',
|
||||
span: 8,
|
||||
props: {
|
||||
placeholder: t('project.node.dynamic_value_tips'),
|
||||
maxLength: 256
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.dynamic_value_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'separator',
|
||||
span: 4,
|
||||
props: {
|
||||
placeholder: t('project.node.dynamic_separator_tips'),
|
||||
maxLength: 256
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.dynamic_separator_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
field: 'filterCondition',
|
||||
span: 24,
|
||||
name: t('project.node.filter_condition')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useCustomParams } from '.'
|
||||
import type { IJsonItem } from '../types'
|
||||
import { computed } from 'vue'
|
||||
|
||||
export function useEmr(model: { [field: string]: any }): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
|
||||
const jobFlowDefineJsonSpan = computed(() =>
|
||||
model.programType === 'RUN_JOB_FLOW' ? 24 : 0
|
||||
)
|
||||
|
||||
const stepsDefineJsonSpan = computed(() =>
|
||||
model.programType === 'ADD_JOB_FLOW_STEPS' ? 24 : 0
|
||||
)
|
||||
|
||||
return [
|
||||
{
|
||||
type: 'select',
|
||||
field: 'programType',
|
||||
span: 24,
|
||||
name: t('project.node.program_type'),
|
||||
options: PROGRAM_TYPES,
|
||||
validate: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
field: 'jobFlowDefineJson',
|
||||
span: jobFlowDefineJsonSpan,
|
||||
name: t('project.node.emr_flow_define_json'),
|
||||
props: {
|
||||
language: 'json'
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'trigger'],
|
||||
required: true,
|
||||
message: t('project.node.emr_flow_define_json_tips')
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'editor',
|
||||
field: 'stepsDefineJson',
|
||||
span: stepsDefineJsonSpan,
|
||||
name: t('project.node.emr_steps_define_json'),
|
||||
props: {
|
||||
language: 'json'
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'trigger'],
|
||||
required: true,
|
||||
message: t('project.node.emr_steps_define_json_tips')
|
||||
}
|
||||
},
|
||||
...useCustomParams({
|
||||
model,
|
||||
field: 'localParams',
|
||||
isSimple: true
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
export const PROGRAM_TYPES = [
|
||||
{
|
||||
label: 'RUN_JOB_FLOW',
|
||||
value: 'RUN_JOB_FLOW'
|
||||
},
|
||||
{
|
||||
label: 'ADD_JOB_FLOW_STEPS',
|
||||
value: 'ADD_JOB_FLOW_STEPS'
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { queryAllEnvironmentList } from '@/service/modules/environment'
|
||||
import type { IEnvironmentNameOption, IJsonItem } from '../types'
|
||||
|
||||
export function useEnvironmentName(
|
||||
model: { [field: string]: any },
|
||||
isCreate: boolean
|
||||
): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
let environmentList = [] as IEnvironmentNameOption[]
|
||||
const options = ref([] as IEnvironmentNameOption[])
|
||||
const loading = ref(false)
|
||||
let mounted = false
|
||||
|
||||
const getEnvironmentList = async () => {
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
const res = await queryAllEnvironmentList()
|
||||
environmentList = res.map(
|
||||
(item: { code: string; name: string; workerGroups: string[] }) => ({
|
||||
label: item.name,
|
||||
value: item.code,
|
||||
workerGroups: item.workerGroups
|
||||
})
|
||||
)
|
||||
options.value = environmentList.filter((option: IEnvironmentNameOption) =>
|
||||
filterByWorkerGroup(option)
|
||||
)
|
||||
loading.value = false
|
||||
if (options.value.length === 0) {
|
||||
model.environmentCode = null
|
||||
} else {
|
||||
isCreate &&
|
||||
!model.environmentCode &&
|
||||
(model.environmentCode = options.value[0].value)
|
||||
}
|
||||
}
|
||||
|
||||
const filterByWorkerGroup = (option: IEnvironmentNameOption) => {
|
||||
if (!model.workerGroup) return false
|
||||
if (!option?.workerGroups?.length) return false
|
||||
return option.workerGroups.indexOf(model.workerGroup) !== -1
|
||||
}
|
||||
|
||||
watch(
|
||||
() => model.workerGroup,
|
||||
() => {
|
||||
if (!model.workerGroup || !mounted) return
|
||||
options.value = environmentList.filter((option: IEnvironmentNameOption) =>
|
||||
filterByWorkerGroup(option)
|
||||
)
|
||||
if (model?.environmentCode) {
|
||||
if (options.value) {
|
||||
const elementExists =
|
||||
options.value.find(
|
||||
(item) => item.value === model.environmentCode
|
||||
) !== undefined
|
||||
if (!elementExists) {
|
||||
model.environmentCode = null
|
||||
}
|
||||
}
|
||||
} else {
|
||||
model.environmentCode =
|
||||
options.value.length === 0 ? null : options.value[0].value
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
await getEnvironmentList()
|
||||
mounted = true
|
||||
})
|
||||
|
||||
return {
|
||||
type: 'select',
|
||||
field: 'environmentCode',
|
||||
class: 'env-select',
|
||||
span: 12,
|
||||
name: t('project.node.environment_name'),
|
||||
props: {
|
||||
loading: loading,
|
||||
clearable: true
|
||||
},
|
||||
options: options
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useExecutorCores(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
type: 'input-number',
|
||||
field: 'executorCores',
|
||||
name: t('project.node.executor_cores'),
|
||||
span: 12,
|
||||
props: {
|
||||
placeholder: t('project.node.executor_cores_tips'),
|
||||
min: 1
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.executor_cores_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useExecutorMemory(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
type: 'input',
|
||||
field: 'executorMemory',
|
||||
name: t('project.node.executor_memory'),
|
||||
span: 12,
|
||||
props: {
|
||||
placeholder: t('project.node.executor_memory_tips')
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.executor_memory_tips'))
|
||||
}
|
||||
if (!Number.isInteger(parseInt(value))) {
|
||||
return new Error(
|
||||
t('project.node.executor_memory_tips') +
|
||||
t('project.node.positive_integer_tips')
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useExecutorNumber(): IJsonItem {
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
type: 'input-number',
|
||||
field: 'numExecutors',
|
||||
name: t('project.node.executor_number'),
|
||||
span: 12,
|
||||
props: {
|
||||
placeholder: t('project.node.executor_number_tips'),
|
||||
min: 1
|
||||
},
|
||||
validate: {
|
||||
trigger: ['input', 'blur'],
|
||||
required: true,
|
||||
validator(validate: any, value: string) {
|
||||
if (!value) {
|
||||
return new Error(t('project.node.executor_number_tips'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { IJsonItem } from '../types'
|
||||
|
||||
export function useFailed(): IJsonItem[] {
|
||||
const { t } = useI18n()
|
||||
return [
|
||||
{
|
||||
type: 'input-number',
|
||||
field: 'failRetryTimes',
|
||||
name: t('project.node.number_of_failed_retries'),
|
||||
span: 12,
|
||||
props: {
|
||||
min: 0
|
||||
},
|
||||
slots: {
|
||||
suffix: () => t('project.node.times')
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'input-number',
|
||||
field: 'failRetryInterval',
|
||||
name: t('project.node.failed_retry_interval'),
|
||||
span: 12,
|
||||
props: {
|
||||
min: 0
|
||||
},
|
||||
slots: {
|
||||
suffix: () => t('project.node.minute')
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue