xiangzihao
4 months ago
committed by
GitHub
48 changed files with 38 additions and 1211 deletions
@ -1,22 +0,0 @@ |
|||||||
# Pigeon |
|
||||||
|
|
||||||
## Overview |
|
||||||
|
|
||||||
Pigeon is a task used to trigger remote tasks, acquire logs or status by calling remote WebSocket service. It is DolphinScheduler uses a remote WebSocket service to call tasks. |
|
||||||
|
|
||||||
## Create Task |
|
||||||
|
|
||||||
- Click `Project Management -> Project Name -> Workflow Definition`, and click the `Create Workflow` button to enter the DAG editing page. |
|
||||||
- Drag from the toolbar <img src="../../../../img/pigeon.png" width="20"/> to the canvas to create a new Pigeon task. |
|
||||||
|
|
||||||
## Task Parameters |
|
||||||
|
|
||||||
[//]: # (TODO: use the commented anchor below once our website template supports this syntax) |
|
||||||
[//]: # (- Please refer to [DolphinScheduler Task Parameters Appendix](appendix.md#default-task-parameters) `Default Task Parameters` section for default parameters.) |
|
||||||
|
|
||||||
- Please refer to [DolphinScheduler Task Parameters Appendix](appendix.md) `Default Task Parameters` section for default parameters. |
|
||||||
|
|
||||||
| **Parameter** | **Description** | |
|
||||||
|------------------|---------------------------------------| |
|
||||||
| Target task name | Target task name of this Pigeon node. | |
|
||||||
|
|
@ -1,19 +0,0 @@ |
|||||||
# Pigeon |
|
||||||
|
|
||||||
Pigeon任务类型是通过调用远程websocket服务,实现远程任务的触发,状态、日志的获取,是 DolphinScheduler 通用远程 websocket 服务调用任务 |
|
||||||
|
|
||||||
## 创建任务 |
|
||||||
|
|
||||||
拖动工具栏中的<img src="../../../../img/pigeon.png" width="20"/>任务节点到画板中即能完成任务创建 |
|
||||||
|
|
||||||
## 任务参数 |
|
||||||
|
|
||||||
[//]: # (TODO: use the commented anchor below once our website template supports this syntax) |
|
||||||
[//]: # (- 默认参数说明请参考[DolphinScheduler任务参数附录](appendix.md#默认任务参数)`默认任务参数`一栏。) |
|
||||||
|
|
||||||
- 默认参数说明请参考[DolphinScheduler任务参数附录](appendix.md)`默认任务参数`一栏。 |
|
||||||
|
|
||||||
| **任务参数** | **描述** | |
|
||||||
|----------|-------------------| |
|
||||||
| 目标任务名 | 输入Pigeon任务的目标任务名称 | |
|
||||||
|
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,22 +0,0 @@ |
|||||||
Copyright (c) 2010-2020 Nathan Rajlich |
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person |
|
||||||
obtaining a copy of this software and associated documentation |
|
||||||
files (the "Software"), to deal in the Software without |
|
||||||
restriction, including without limitation the rights to use, |
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
||||||
copies of the Software, and to permit persons to whom the |
|
||||||
Software is furnished to do so, subject to the following |
|
||||||
conditions: |
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be |
|
||||||
included in all copies or substantial portions of the Software. |
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
|
||||||
OTHER DEALINGS IN THE SOFTWARE. |
|
@ -1,85 +0,0 @@ |
|||||||
<?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-pigeon</artifactId> |
|
||||||
<packaging>jar</packaging> |
|
||||||
<dependencies> |
|
||||||
|
|
||||||
<dependency> |
|
||||||
<groupId>org.apache.dolphinscheduler</groupId> |
|
||||||
<artifactId>dolphinscheduler-task-api</artifactId> |
|
||||||
<version>${project.version}</version> |
|
||||||
</dependency> |
|
||||||
<dependency> |
|
||||||
<groupId>org.apache.dolphinscheduler</groupId> |
|
||||||
<artifactId>dolphinscheduler-spi</artifactId> |
|
||||||
<scope>provided</scope> |
|
||||||
</dependency> |
|
||||||
<dependency> |
|
||||||
<groupId>org.apache.commons</groupId> |
|
||||||
<artifactId>commons-collections4</artifactId> |
|
||||||
</dependency> |
|
||||||
<dependency> |
|
||||||
<groupId>org.slf4j</groupId> |
|
||||||
<artifactId>slf4j-api</artifactId> |
|
||||||
</dependency> |
|
||||||
|
|
||||||
<!--https://github.com/dreamhead/moco/blob/master/moco-doc/usage.md#socket--> |
|
||||||
<dependency> |
|
||||||
<groupId>com.github.dreamhead</groupId> |
|
||||||
<artifactId>moco-core</artifactId> |
|
||||||
<version>1.2.0</version> |
|
||||||
<scope>test</scope> |
|
||||||
</dependency> |
|
||||||
<dependency> |
|
||||||
<groupId>com.github.dreamhead</groupId> |
|
||||||
<artifactId>moco-runner</artifactId> |
|
||||||
<version>1.2.0</version> |
|
||||||
<scope>test</scope> |
|
||||||
<exclusions> |
|
||||||
<exclusion> |
|
||||||
<groupId>commons-cli</groupId> |
|
||||||
<artifactId>commons-cli</artifactId> |
|
||||||
</exclusion> |
|
||||||
</exclusions> |
|
||||||
</dependency> |
|
||||||
|
|
||||||
<dependency> |
|
||||||
<groupId>org.java-websocket</groupId> |
|
||||||
<artifactId>Java-WebSocket</artifactId> |
|
||||||
</dependency> |
|
||||||
|
|
||||||
<dependency> |
|
||||||
<groupId>org.apache.httpcomponents</groupId> |
|
||||||
<artifactId>httpclient</artifactId> |
|
||||||
</dependency> |
|
||||||
<dependency> |
|
||||||
<groupId>org.apache.httpcomponents</groupId> |
|
||||||
<artifactId>httpcore</artifactId> |
|
||||||
</dependency> |
|
||||||
</dependencies> |
|
||||||
</project> |
|
@ -1,86 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.pigeon; |
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils; |
|
||||||
|
|
||||||
import java.util.ResourceBundle; |
|
||||||
|
|
||||||
public class PigeonConfig { |
|
||||||
|
|
||||||
private static PigeonConfig cfg; |
|
||||||
|
|
||||||
private final String jobTriggerUrl; |
|
||||||
private final String jobTriggerPostBody; |
|
||||||
private final String jobStatusUrl; |
|
||||||
private final String jobStatusPostBody; |
|
||||||
|
|
||||||
private final String jobLogsFetchUrl; |
|
||||||
private final String jobCancelPostBody; |
|
||||||
|
|
||||||
public static synchronized PigeonConfig getInstance() { |
|
||||||
if (cfg == null) { |
|
||||||
cfg = new PigeonConfig(); |
|
||||||
} |
|
||||||
return cfg; |
|
||||||
} |
|
||||||
|
|
||||||
private PigeonConfig() { |
|
||||||
ResourceBundle bundle = |
|
||||||
ResourceBundle.getBundle(PigeonConfig.class.getPackage().getName().replace(".", "/") + "/config"); |
|
||||||
this.jobTriggerUrl = bundle.getString("job.trigger.url"); |
|
||||||
this.jobStatusUrl = bundle.getString("job.status.url"); |
|
||||||
this.jobTriggerPostBody = bundle.getString("job.trigger.post.body"); |
|
||||||
this.jobStatusPostBody = bundle.getString("job.status.post.body"); |
|
||||||
this.jobLogsFetchUrl = bundle.getString("job.logs.fetch.url"); |
|
||||||
this.jobCancelPostBody = bundle.getString("job.cancel.post.body"); |
|
||||||
} |
|
||||||
|
|
||||||
public String getJobCancelPostBody(int taskId) { |
|
||||||
return String.format(jobCancelPostBody, taskId); |
|
||||||
} |
|
||||||
|
|
||||||
public String getJobTriggerUrl(String tisHost) { |
|
||||||
checkHost(tisHost); |
|
||||||
return String.format(this.jobTriggerUrl, tisHost); |
|
||||||
} |
|
||||||
|
|
||||||
public String getJobTriggerPostBody() { |
|
||||||
return jobTriggerPostBody; |
|
||||||
} |
|
||||||
|
|
||||||
public String getJobStatusPostBody(int taskId) { |
|
||||||
return String.format(jobStatusPostBody, taskId); |
|
||||||
} |
|
||||||
|
|
||||||
public String getJobLogsFetchUrl(String host, String jobName, int taskId) { |
|
||||||
checkHost(host); |
|
||||||
return String.format(jobLogsFetchUrl, host, jobName, taskId); |
|
||||||
} |
|
||||||
|
|
||||||
public String getJobStatusUrl(String tisHost) { |
|
||||||
checkHost(tisHost); |
|
||||||
return String.format(this.jobStatusUrl, tisHost); |
|
||||||
} |
|
||||||
|
|
||||||
private static void checkHost(String tisHost) { |
|
||||||
if (StringUtils.isBlank(tisHost)) { |
|
||||||
throw new IllegalArgumentException("param tisHost can not be null"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,62 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.pigeon; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.model.ResourceInfo; |
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters; |
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils; |
|
||||||
|
|
||||||
import java.util.Collections; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j; |
|
||||||
|
|
||||||
/** |
|
||||||
* TIS parameter |
|
||||||
*/ |
|
||||||
@Slf4j |
|
||||||
public class PigeonParameters extends AbstractParameters { |
|
||||||
|
|
||||||
/** |
|
||||||
* Pigeon target job name |
|
||||||
*/ |
|
||||||
private String targetJobName; |
|
||||||
|
|
||||||
public String getTargetJobName() { |
|
||||||
return targetJobName; |
|
||||||
} |
|
||||||
|
|
||||||
public void setTargetJobName(String targetJobName) { |
|
||||||
this.targetJobName = targetJobName; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean checkParameters() { |
|
||||||
if (StringUtils.isBlank(this.targetJobName)) { |
|
||||||
log.error("checkParameters faild targetJobName can not be null"); |
|
||||||
return false; |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public List<ResourceInfo> getResourceFilesList() { |
|
||||||
return Collections.emptyList(); |
|
||||||
} |
|
||||||
} |
|
@ -1,27 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.pigeon; |
|
||||||
|
|
||||||
public class PigeonParamsConstants { |
|
||||||
|
|
||||||
public static String NAME_TARGET_JOB_NAME = "targetJobName"; |
|
||||||
public static String TARGET_JOB_NAME = NAME_TARGET_JOB_NAME; |
|
||||||
|
|
||||||
private PigeonParamsConstants() { |
|
||||||
} |
|
||||||
} |
|
@ -1,430 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.pigeon; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.common.utils.JSONUtils; |
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.AbstractRemoteTask; |
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.TaskCallBack; |
|
||||||
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 org.apache.dolphinscheduler.plugin.task.api.parameters.AbstractParameters; |
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils; |
|
||||||
import org.apache.commons.lang3.StringUtils; |
|
||||||
import org.apache.http.HttpEntity; |
|
||||||
import org.apache.http.StatusLine; |
|
||||||
import org.apache.http.client.ClientProtocolException; |
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse; |
|
||||||
import org.apache.http.client.methods.HttpPost; |
|
||||||
import org.apache.http.entity.StringEntity; |
|
||||||
import org.apache.http.impl.client.CloseableHttpClient; |
|
||||||
import org.apache.http.impl.client.HttpClients; |
|
||||||
import org.apache.http.util.EntityUtils; |
|
||||||
|
|
||||||
import java.net.HttpURLConnection; |
|
||||||
import java.net.URI; |
|
||||||
import java.nio.charset.StandardCharsets; |
|
||||||
import java.util.Collections; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.Objects; |
|
||||||
import java.util.stream.Collectors; |
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j; |
|
||||||
|
|
||||||
import org.java_websocket.client.WebSocketClient; |
|
||||||
import org.java_websocket.handshake.ServerHandshake; |
|
||||||
|
|
||||||
/** |
|
||||||
* TIS DataX Task |
|
||||||
**/ |
|
||||||
@Slf4j |
|
||||||
public class PigeonTask extends AbstractRemoteTask { |
|
||||||
|
|
||||||
public static final String KEY_POOL_VAR_PIGEON_HOST = "p_host"; |
|
||||||
private final TaskExecutionContext taskExecutionContext; |
|
||||||
|
|
||||||
private PigeonParameters parameters; |
|
||||||
private BizResult triggerResult; |
|
||||||
private final PigeonConfig config; |
|
||||||
|
|
||||||
public PigeonTask(TaskExecutionContext taskExecutionContext) { |
|
||||||
super(taskExecutionContext); |
|
||||||
this.taskExecutionContext = taskExecutionContext; |
|
||||||
this.config = PigeonConfig.getInstance(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public List<String> getApplicationIds() throws TaskException { |
|
||||||
return Collections.emptyList(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void init() throws TaskException { |
|
||||||
super.init(); |
|
||||||
parameters = JSONUtils.parseObject(taskExecutionContext.getTaskParams(), PigeonParameters.class); |
|
||||||
log.info("Initialize PIGEON task params {}", JSONUtils.toPrettyJsonString(parameters)); |
|
||||||
if (parameters == null || !parameters.checkParameters()) { |
|
||||||
throw new TaskException("datax task params is not valid"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// todo split handle to submit and track
|
|
||||||
@Override |
|
||||||
public void handle(TaskCallBack taskCallBack) throws TaskException { |
|
||||||
// Trigger PIGEON DataX pipeline
|
|
||||||
log.info("start execute PIGEON task"); |
|
||||||
long startTime = System.currentTimeMillis(); |
|
||||||
String targetJobName = this.parameters.getTargetJobName(); |
|
||||||
String host = getHost(); |
|
||||||
try { |
|
||||||
final String triggerUrl = getTriggerUrl(); |
|
||||||
final String getStatusUrl = config.getJobStatusUrl(host); |
|
||||||
HttpPost post = new HttpPost(triggerUrl); |
|
||||||
post.addHeader("appname", targetJobName); |
|
||||||
addFormUrlencoded(post); |
|
||||||
StringEntity entity = new StringEntity(config.getJobTriggerPostBody(), StandardCharsets.UTF_8); |
|
||||||
post.setEntity(entity); |
|
||||||
ExecResult execState = null; |
|
||||||
int taskId; |
|
||||||
WebSocketClient webSocket = null; |
|
||||||
try ( |
|
||||||
CloseableHttpClient client = HttpClients.createDefault(); |
|
||||||
// trigger to start PIGEON dataX task
|
|
||||||
CloseableHttpResponse response = client.execute(post)) { |
|
||||||
triggerResult = processResponse(triggerUrl, response, BizResult.class); |
|
||||||
if (!triggerResult.isSuccess()) { |
|
||||||
List<String> errormsg = triggerResult.getErrormsg(); |
|
||||||
StringBuffer errs = new StringBuffer(); |
|
||||||
if (CollectionUtils.isNotEmpty(errormsg)) { |
|
||||||
errs.append(",errs:").append(errormsg.stream().collect(Collectors.joining(","))); |
|
||||||
} |
|
||||||
throw new Exception("trigger PIGEON job faild taskName:" + targetJobName + errs.toString()); |
|
||||||
} |
|
||||||
taskId = triggerResult.getBizresult().getTaskid(); |
|
||||||
|
|
||||||
webSocket = receiveRealtimeLog(host, targetJobName, taskId); |
|
||||||
|
|
||||||
setAppIds(String.valueOf(taskId)); |
|
||||||
|
|
||||||
CloseableHttpResponse status = null; |
|
||||||
|
|
||||||
while (true) { |
|
||||||
try { |
|
||||||
post = new HttpPost(getStatusUrl); |
|
||||||
entity = new StringEntity("{\n taskid: " + taskId + "\n, log: false }", StandardCharsets.UTF_8); |
|
||||||
post.setEntity(entity); |
|
||||||
status = client.execute(post); |
|
||||||
StatusResult execStatus = processResponse(getStatusUrl, status, StatusResult.class); |
|
||||||
Map bizresult = execStatus.getBizresult(); |
|
||||||
Map s = (Map) bizresult.get("status"); |
|
||||||
execState = ExecResult.parse((Integer) s.get("state")); |
|
||||||
if (execState == ExecResult.SUCCESS || execState == ExecResult.FAILD) { |
|
||||||
break; |
|
||||||
} |
|
||||||
Thread.sleep(3000); |
|
||||||
} finally { |
|
||||||
status.close(); |
|
||||||
} |
|
||||||
} |
|
||||||
} finally { |
|
||||||
if (webSocket != null) { |
|
||||||
Thread.sleep(4000); |
|
||||||
try { |
|
||||||
webSocket.close(); |
|
||||||
} catch (Throwable e) { |
|
||||||
log.warn(e.getMessage(), e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
long costTime = System.currentTimeMillis() - startTime; |
|
||||||
log.info("PIGEON task: {},taskId:{} costTime : {} milliseconds, statusCode : {}", |
|
||||||
targetJobName, taskId, costTime, (execState == ExecResult.SUCCESS) ? "'success'" : "'failure'"); |
|
||||||
setExitStatusCode((execState == ExecResult.SUCCESS) ? TaskConstants.EXIT_CODE_SUCCESS |
|
||||||
: TaskConstants.EXIT_CODE_FAILURE); |
|
||||||
} catch (Exception e) { |
|
||||||
log.error("execute PIGEON dataX faild,PIGEON task name:" + targetJobName, e); |
|
||||||
setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE); |
|
||||||
if (e instanceof InterruptedException) { |
|
||||||
Thread.currentThread().interrupt(); |
|
||||||
} |
|
||||||
throw new TaskException("Execute pigeon task failed", e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void submitApplication() throws TaskException { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void trackApplicationStatus() throws TaskException { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
private void addFormUrlencoded(HttpPost post) { |
|
||||||
post.addHeader("content-type", "application/x-www-form-urlencoded"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void cancelApplication() throws TaskException { |
|
||||||
log.info("start to cancelApplication"); |
|
||||||
Objects.requireNonNull(triggerResult, "triggerResult can not be null"); |
|
||||||
log.info("start to cancelApplication taskId:{}", triggerResult.getTaskId()); |
|
||||||
final String triggerUrl = getTriggerUrl(); |
|
||||||
|
|
||||||
StringEntity entity = |
|
||||||
new StringEntity(config.getJobCancelPostBody(triggerResult.getTaskId()), StandardCharsets.UTF_8); |
|
||||||
|
|
||||||
CancelResult cancelResult = null; |
|
||||||
HttpPost post = new HttpPost(triggerUrl); |
|
||||||
addFormUrlencoded(post); |
|
||||||
post.setEntity(entity); |
|
||||||
try ( |
|
||||||
CloseableHttpClient client = HttpClients.createDefault(); |
|
||||||
// trigger to start TIS dataX task
|
|
||||||
CloseableHttpResponse response = client.execute(post)) { |
|
||||||
cancelResult = processResponse(triggerUrl, response, CancelResult.class); |
|
||||||
if (!cancelResult.isSuccess()) { |
|
||||||
List<String> errormsg = triggerResult.getErrormsg(); |
|
||||||
StringBuffer errs = new StringBuffer(); |
|
||||||
if (CollectionUtils.isNotEmpty(errormsg)) { |
|
||||||
errs.append(",errs:").append(errormsg.stream().collect(Collectors.joining(","))); |
|
||||||
} |
|
||||||
throw new TaskException("cancel PIGEON job faild taskId:" + triggerResult.getTaskId() + errs); |
|
||||||
} |
|
||||||
} catch (ClientProtocolException e) { |
|
||||||
throw new TaskException("client protocol error", e); |
|
||||||
} catch (Exception e) { |
|
||||||
throw new TaskException("pigeon execute error", e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private String getTriggerUrl() { |
|
||||||
final String tisHost = getHost(); |
|
||||||
return config.getJobTriggerUrl(tisHost); |
|
||||||
} |
|
||||||
|
|
||||||
private String getHost() { |
|
||||||
final String host = taskExecutionContext.getDefinedParams().get(KEY_POOL_VAR_PIGEON_HOST); |
|
||||||
if (StringUtils.isEmpty(host)) { |
|
||||||
throw new IllegalStateException("global var '" + KEY_POOL_VAR_PIGEON_HOST + "' can not be empty"); |
|
||||||
} |
|
||||||
return host; |
|
||||||
} |
|
||||||
|
|
||||||
private WebSocketClient receiveRealtimeLog(final String tisHost, String dataXName, int taskId) throws Exception { |
|
||||||
final String applyURI = config.getJobLogsFetchUrl(tisHost, dataXName, taskId); |
|
||||||
log.info("apply ws connection,uri:{}", applyURI); |
|
||||||
WebSocketClient webSocketClient = new WebSocketClient(new URI(applyURI)) { |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onOpen(ServerHandshake handshakedata) { |
|
||||||
log.info("start to receive remote execute log"); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onMessage(String message) { |
|
||||||
ExecLog execLog = JSONUtils.parseObject(message, ExecLog.class); |
|
||||||
log.info(execLog.getMsg()); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onClose(int code, String reason, boolean remote) { |
|
||||||
log.info("stop to receive remote log,reason:{},taskId:{}", reason, taskId); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onError(Exception t) { |
|
||||||
log.error(t.getMessage(), t); |
|
||||||
} |
|
||||||
}; |
|
||||||
webSocketClient.connect(); |
|
||||||
return webSocketClient; |
|
||||||
} |
|
||||||
|
|
||||||
private <T extends AjaxResult> T processResponse(String applyUrl, CloseableHttpResponse response, |
|
||||||
Class<T> clazz) throws Exception { |
|
||||||
StatusLine resStatus = response.getStatusLine(); |
|
||||||
if (HttpURLConnection.HTTP_OK != resStatus.getStatusCode()) { |
|
||||||
throw new IllegalStateException("request server " + applyUrl + " faild:" + resStatus.getReasonPhrase()); |
|
||||||
} |
|
||||||
HttpEntity entity = response.getEntity(); |
|
||||||
String resp = EntityUtils.toString(entity, StandardCharsets.UTF_8); |
|
||||||
T result = JSONUtils.parseObject(resp, clazz); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public AbstractParameters getParameters() { |
|
||||||
Objects.requireNonNull(this.parameters, "tisParameters can not be null"); |
|
||||||
return this.parameters; |
|
||||||
} |
|
||||||
|
|
||||||
private static class CancelResult extends AjaxResult<Object> { |
|
||||||
|
|
||||||
private Object bizresult; |
|
||||||
|
|
||||||
@Override |
|
||||||
public Object getBizresult() { |
|
||||||
return this.bizresult; |
|
||||||
} |
|
||||||
|
|
||||||
public void setBizresult(Object bizresult) { |
|
||||||
this.bizresult = bizresult; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static class BizResult extends AjaxResult<TriggerBuildResult> { |
|
||||||
|
|
||||||
private TriggerBuildResult bizresult; |
|
||||||
|
|
||||||
@Override |
|
||||||
public TriggerBuildResult getBizresult() { |
|
||||||
return this.bizresult; |
|
||||||
} |
|
||||||
|
|
||||||
public int getTaskId() { |
|
||||||
return bizresult.taskid; |
|
||||||
} |
|
||||||
|
|
||||||
public void setBizresult(TriggerBuildResult bizresult) { |
|
||||||
this.bizresult = bizresult; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static class StatusResult extends AjaxResult<Map> { |
|
||||||
|
|
||||||
private Map bizresult; |
|
||||||
|
|
||||||
@Override |
|
||||||
public Map getBizresult() { |
|
||||||
return this.bizresult; |
|
||||||
} |
|
||||||
|
|
||||||
public void setBizresult(Map bizresult) { |
|
||||||
this.bizresult = bizresult; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private abstract static class AjaxResult<T> { |
|
||||||
|
|
||||||
private boolean success; |
|
||||||
|
|
||||||
private List<String> errormsg; |
|
||||||
|
|
||||||
private List<String> msg; |
|
||||||
|
|
||||||
public abstract T getBizresult(); |
|
||||||
|
|
||||||
public boolean isSuccess() { |
|
||||||
return success; |
|
||||||
} |
|
||||||
|
|
||||||
public void setSuccess(boolean success) { |
|
||||||
this.success = success; |
|
||||||
} |
|
||||||
|
|
||||||
public List<String> getErrormsg() { |
|
||||||
return this.errormsg; |
|
||||||
} |
|
||||||
|
|
||||||
public void setErrormsg(List<String> errormsg) { |
|
||||||
this.errormsg = errormsg; |
|
||||||
} |
|
||||||
|
|
||||||
public List<String> getMsg() { |
|
||||||
return this.msg; |
|
||||||
} |
|
||||||
|
|
||||||
public void setMsg(List<String> msg) { |
|
||||||
this.msg = msg; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
private static class TriggerBuildResult { |
|
||||||
|
|
||||||
private int taskid; |
|
||||||
|
|
||||||
public int getTaskid() { |
|
||||||
return taskid; |
|
||||||
} |
|
||||||
|
|
||||||
public void setTaskid(int taskid) { |
|
||||||
this.taskid = taskid; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private enum ExecResult { |
|
||||||
|
|
||||||
SUCCESS(1), FAILD(-1), DOING(2), ASYN_DOING(22), CANCEL(3); |
|
||||||
|
|
||||||
private final int value; |
|
||||||
|
|
||||||
public static ExecResult parse(int value) { |
|
||||||
for (ExecResult r : values()) { |
|
||||||
if (r.value == value) { |
|
||||||
return r; |
|
||||||
} |
|
||||||
} |
|
||||||
throw new IllegalStateException("vale:" + value + " is illegal"); |
|
||||||
} |
|
||||||
|
|
||||||
private ExecResult(int value) { |
|
||||||
this.value = value; |
|
||||||
} |
|
||||||
|
|
||||||
public int getValue() { |
|
||||||
return this.value; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static class ExecLog { |
|
||||||
|
|
||||||
private String logType; |
|
||||||
private String msg; |
|
||||||
private int taskId; |
|
||||||
|
|
||||||
public String getLogType() { |
|
||||||
return logType; |
|
||||||
} |
|
||||||
|
|
||||||
public void setLogType(String logType) { |
|
||||||
this.logType = logType; |
|
||||||
} |
|
||||||
|
|
||||||
public String getMsg() { |
|
||||||
return msg; |
|
||||||
} |
|
||||||
|
|
||||||
public void setMsg(String msg) { |
|
||||||
this.msg = msg; |
|
||||||
} |
|
||||||
|
|
||||||
public int getTaskId() { |
|
||||||
return taskId; |
|
||||||
} |
|
||||||
|
|
||||||
public void setTaskId(int taskId) { |
|
||||||
this.taskId = taskId; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,41 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.pigeon; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.common.utils.JSONUtils; |
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.AbstractTask; |
|
||||||
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 lombok.extern.slf4j.Slf4j; |
|
||||||
|
|
||||||
@Slf4j |
|
||||||
public class PigeonTaskChannel implements TaskChannel { |
|
||||||
|
|
||||||
@Override |
|
||||||
public AbstractTask createTask(TaskExecutionContext taskRequest) { |
|
||||||
return new PigeonTask(taskRequest); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public AbstractParameters parseParameters(String taskParams) { |
|
||||||
return JSONUtils.parseObject(taskParams, PigeonParameters.class); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,38 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.pigeon; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.TaskChannel; |
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.TaskChannelFactory; |
|
||||||
|
|
||||||
import com.google.auto.service.AutoService; |
|
||||||
|
|
||||||
@AutoService(TaskChannelFactory.class) |
|
||||||
public class PigeonTaskChannelFactory implements TaskChannelFactory { |
|
||||||
|
|
||||||
@Override |
|
||||||
public TaskChannel create() { |
|
||||||
return new PigeonTaskChannel(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getName() { |
|
||||||
return "PIGEON"; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,26 +0,0 @@ |
|||||||
# |
|
||||||
# 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. |
|
||||||
# |
|
||||||
|
|
||||||
job.trigger.url=http://%s/tjs/coredefine/coredefine.ajax |
|
||||||
job.trigger.post.body=action=datax_action&emethod=trigger_fullbuild_task |
|
||||||
|
|
||||||
job.cancel.post.body=action=core_action&event_submit_do_cancel_task=y&taskid=%s |
|
||||||
|
|
||||||
job.status.url=http://%s/tjs/config/config.ajax?action=collection_action&emethod=get_task_status |
|
||||||
job.status.post.body={\n taskid: %s\n, log: false } |
|
||||||
|
|
||||||
job.logs.fetch.url=ws://%s/tjs/download/logfeedback?logtype=full&collection=%s&taskid=%s |
|
@ -1,142 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.pigeon; |
|
||||||
|
|
||||||
import static com.github.dreamhead.moco.Moco.file; |
|
||||||
import static com.github.dreamhead.moco.MocoJsonRunner.jsonHttpServer; |
|
||||||
import static com.github.dreamhead.moco.Runner.running; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.TaskExecutionContext; |
|
||||||
import org.apache.dolphinscheduler.plugin.task.api.enums.TaskExecutionStatus; |
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils; |
|
||||||
|
|
||||||
import java.io.InputStream; |
|
||||||
import java.nio.charset.StandardCharsets; |
|
||||||
import java.util.Collections; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.Objects; |
|
||||||
import java.util.UUID; |
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions; |
|
||||||
import org.junit.jupiter.api.BeforeEach; |
|
||||||
import org.junit.jupiter.api.Test; |
|
||||||
import org.mockito.Mockito; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
import com.github.dreamhead.moco.HttpServer; |
|
||||||
|
|
||||||
public class PigeonTaskTest { |
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PigeonTaskTest.class); |
|
||||||
private PigeonTask pigeonTask; |
|
||||||
|
|
||||||
private TaskExecutionContext taskExecutionContext; |
|
||||||
|
|
||||||
@BeforeEach |
|
||||||
public void before() throws Exception { |
|
||||||
|
|
||||||
String taskParams = "{\"targetJobName\":\"mysql_elastic\"}"; |
|
||||||
|
|
||||||
taskExecutionContext = Mockito.mock(TaskExecutionContext.class); |
|
||||||
Mockito.when(taskExecutionContext.getTaskParams()).thenReturn(taskParams); |
|
||||||
Mockito.when(taskExecutionContext.getExecutePath()).thenReturn("/tmp"); |
|
||||||
Mockito.when(taskExecutionContext.getTaskAppId()).thenReturn(UUID.randomUUID().toString()); |
|
||||||
Mockito.when(taskExecutionContext.getTenantCode()).thenReturn("root"); |
|
||||||
Mockito.when(taskExecutionContext.getStartTime()).thenReturn(System.currentTimeMillis()); |
|
||||||
Mockito.when(taskExecutionContext.getTaskTimeout()).thenReturn(10000); |
|
||||||
Mockito.when(taskExecutionContext.getLogPath()).thenReturn("/tmp/dx"); |
|
||||||
// Mockito.when(taskExecutionContext.getVarPool())
|
|
||||||
// .thenReturn("[{\"direct\":\"IN\",\"prop\":\"" + TISTask.KEY_POOL_VAR_TIS_HOST +
|
|
||||||
// "\",\"type\":\"VARCHAR\",\"value\":\"127.0.0.1:8080\"}]");
|
|
||||||
Map<String, String> gloabParams = |
|
||||||
Collections.singletonMap(PigeonTask.KEY_POOL_VAR_PIGEON_HOST, "127.0.0.1:8080"); |
|
||||||
Mockito.when(taskExecutionContext.getDefinedParams()).thenReturn(gloabParams); |
|
||||||
|
|
||||||
pigeonTask = new PigeonTask(taskExecutionContext); |
|
||||||
pigeonTask.init(); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void testGetTISConfigParams() { |
|
||||||
PigeonConfig cfg = PigeonConfig.getInstance(); |
|
||||||
String tisHost = "127.0.0.1:8080"; |
|
||||||
Assertions.assertEquals("http://127.0.0.1:8080/tjs/coredefine/coredefine.ajax", cfg.getJobTriggerUrl(tisHost)); |
|
||||||
String jobName = "mysql_elastic"; |
|
||||||
int taskId = 123; |
|
||||||
Assertions.assertEquals( |
|
||||||
"ws://" + tisHost + "/tjs/download/logfeedback?logtype=full&collection=mysql_elastic&taskid=" + taskId, |
|
||||||
cfg.getJobLogsFetchUrl(tisHost, jobName, taskId)); |
|
||||||
|
|
||||||
Assertions.assertEquals("action=datax_action&emethod=trigger_fullbuild_task", cfg.getJobTriggerPostBody()); |
|
||||||
|
|
||||||
Assertions.assertEquals( |
|
||||||
"http://127.0.0.1:8080/tjs/config/config.ajax?action=collection_action&emethod=get_task_status", |
|
||||||
cfg.getJobStatusUrl(tisHost)); |
|
||||||
|
|
||||||
Assertions.assertEquals("{\n taskid: " + taskId + "\n, log: false }", cfg.getJobStatusPostBody(taskId)); |
|
||||||
|
|
||||||
Assertions.assertEquals("action=core_action&event_submit_do_cancel_task=y&taskid=" + taskId, |
|
||||||
cfg.getJobCancelPostBody(taskId)); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void testInit() throws Exception { |
|
||||||
try { |
|
||||||
pigeonTask.init(); |
|
||||||
} catch (Exception e) { |
|
||||||
Assertions.fail(e.getMessage()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void testHandle() throws Exception { |
|
||||||
HttpServer server = jsonHttpServer(8080, |
|
||||||
file("src/test/resources/org/apache/dolphinscheduler/plugin/task/pigeon/PigeonTaskTest.json")); |
|
||||||
|
|
||||||
running(server, () -> { |
|
||||||
pigeonTask.handle(null); |
|
||||||
|
|
||||||
Assertions.assertEquals(TaskExecutionStatus.SUCCESS, pigeonTask.getExitStatus()); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
private String loadResContent(String resName) { |
|
||||||
try (InputStream i = this.getClass().getResourceAsStream(resName)) { |
|
||||||
Objects.requireNonNull(i, "resource " + resName + " relevant stream content can not be null"); |
|
||||||
String content = IOUtils.toString(i, StandardCharsets.UTF_8); |
|
||||||
|
|
||||||
return content; |
|
||||||
} catch (Exception e) { |
|
||||||
throw new RuntimeException(e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// @Test
|
|
||||||
// public void testCancelApplication()
|
|
||||||
// throws Exception {
|
|
||||||
// try {
|
|
||||||
// tisTask.cancelApplication(true);
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// Assertions.fail(e.getMessage());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
} |
|
@ -1,60 +0,0 @@ |
|||||||
[ |
|
||||||
{ |
|
||||||
"description": "trigger task execute", |
|
||||||
"request": { |
|
||||||
"uri": "/tjs/coredefine/coredefine.ajax", |
|
||||||
"method": "post", |
|
||||||
"headers": { |
|
||||||
"Content-Type": "application/x-www-form-urlencoded", |
|
||||||
"appname": "mysql_elastic" |
|
||||||
}, |
|
||||||
"text": "action=datax_action&emethod=trigger_fullbuild_task" |
|
||||||
}, |
|
||||||
"response": { |
|
||||||
"text": "{\n \"success\":true,\n \"errormsg\":[],\n \"msg\":[],\n \"bizresult\":{\"taskid\": \"1087\"}\n}" |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"description": "Get task execute status", |
|
||||||
"request": { |
|
||||||
"uri": "/tjs/config/config.ajax", |
|
||||||
"method": "post", |
|
||||||
"headers": { |
|
||||||
"Content-Type": "text/plain; charset=UTF-8" |
|
||||||
}, |
|
||||||
"queries": { |
|
||||||
"action": "collection_action", |
|
||||||
"emethod": "get_task_status" |
|
||||||
}, |
|
||||||
"text": "{\n taskid: 1087\n, log: false }" |
|
||||||
}, |
|
||||||
"response": { |
|
||||||
"seq": [ |
|
||||||
{ |
|
||||||
"text": "{\n \"success\": true,\n \"errormsg\": [\n \"err1\"\n ],\n \"bizresult\": {\n \"status\": {\n \"state\": 2\n }\n }\n}" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"text": "{\n \"success\": true,\n \"errormsg\": [\n \"err1\"\n ],\n \"bizresult\": {\n \"status\": {\n \"state\": 1\n }\n }\n}" |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"websocket": { |
|
||||||
"uri": "/tjs/download/logfeedback", |
|
||||||
"connected": "connected", |
|
||||||
"sessions": [ |
|
||||||
{ |
|
||||||
"request": { |
|
||||||
"text": "logtype=full&collection=mysql_elastic&taskid=1087" |
|
||||||
}, |
|
||||||
"response": { |
|
||||||
"broadcast": { |
|
||||||
"content": "{\n \"logType\": \"FULL\",\n \"msg\": \"message 1\",\n \"taskId\": \"1087\"\n}" |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
||||||
} |
|
||||||
] |
|
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
@ -1,68 +0,0 @@ |
|||||||
/* |
|
||||||
* 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 { reactive } from 'vue' |
|
||||||
import * as Fields from '../fields/index' |
|
||||||
import type { IJsonItem, INodeData, ITaskData } from '../types' |
|
||||||
|
|
||||||
export function usePigeon({ |
|
||||||
projectCode, |
|
||||||
from = 0, |
|
||||||
readonly, |
|
||||||
data |
|
||||||
}: { |
|
||||||
projectCode: number |
|
||||||
from?: number |
|
||||||
readonly?: boolean |
|
||||||
data?: ITaskData |
|
||||||
}) { |
|
||||||
const model = reactive({ |
|
||||||
taskType: 'PIGEON', |
|
||||||
name: '', |
|
||||||
flag: 'YES', |
|
||||||
description: '', |
|
||||||
timeoutFlag: false, |
|
||||||
environmentCode: null, |
|
||||||
failRetryInterval: 1, |
|
||||||
failRetryTimes: 0, |
|
||||||
workerGroup: 'default', |
|
||||||
delayTime: 0, |
|
||||||
timeout: 30, |
|
||||||
targetJobName: '', |
|
||||||
timeoutNotifyStrategy: ['WARN'] |
|
||||||
} as INodeData) |
|
||||||
|
|
||||||
return { |
|
||||||
json: [ |
|
||||||
Fields.useName(from), |
|
||||||
...Fields.useTaskDefinition({ projectCode, from, readonly, data, model }), |
|
||||||
Fields.useRunFlag(), |
|
||||||
Fields.useCache(), |
|
||||||
Fields.useDescription(), |
|
||||||
Fields.useTaskPriority(), |
|
||||||
Fields.useWorkerGroup(projectCode), |
|
||||||
Fields.useEnvironmentName(model, !data?.id), |
|
||||||
...Fields.useTaskGroup(model, projectCode), |
|
||||||
...Fields.useFailed(), |
|
||||||
Fields.useDelayTime(model), |
|
||||||
...Fields.useTimeoutAlarm(model), |
|
||||||
Fields.useTargetTaskName(), |
|
||||||
Fields.usePreTasks() |
|
||||||
] as IJsonItem[], |
|
||||||
model |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue