All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.wicp.tams.common.http.flink.FlinkRestApi Maven / Gradle / Ivy

The newest version!
package net.wicp.tams.common.http.flink;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Pair;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;

import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.common.Result;
import net.wicp.tams.common.apiext.IOUtil;
import net.wicp.tams.common.apiext.StringUtil;
import net.wicp.tams.common.apiext.json.JSONUtil;
import net.wicp.tams.common.exception.ExceptAll;
import net.wicp.tams.common.exception.ProjectExceptionRuntime;
import net.wicp.tams.common.http.HttpClient;
import net.wicp.tams.common.http.HttpResult;

//https://nightlies.apache.org/flink/flink-docs-release-1.17/docs/ops/rest_api/#jars-jarid-run
@Slf4j
public class FlinkRestApi {
	private final String jmUrl;

	public FlinkRestApi(String jmUrl) {
		this.jmUrl = jmUrl;
	}

	/**
	 * 提交任务
	 * 
	 * @param taskName
	 * @param parallelism
	 * @param params
	 * @return
	 */
	public Result submitTask(String taskName, String jarId, int parallelism, String savepointPath,
			Map params) {
		ObjectNode inputParam = JsonNodeFactory.instance.objectNode();
		inputParam.put("entryClass", "net.wicp.tams.common.flink.sqlrun.SqlRunner");
		StringBuffer buff = new StringBuffer(String.format("--taskId %s", taskName));
		if (MapUtils.isNotEmpty(params)) {
			params.remove("taskId");// 以taskName为主
			for (String key : params.keySet()) {
				buff.append(" " + String.format("--%s %s", key, params.get(key)));
			}
		}
		inputParam.put("programArgs", buff.toString());
		inputParam.put("parallelism", parallelism);
		if (StringUtil.isNotNull(savepointPath)) {
			inputParam.put("savepointPath", savepointPath);
		}
		String url = IOUtil.mergeFolderAndFilePath(this.jmUrl, String.format("/jars/%s/run", jarId));
		HttpResult doPost = HttpClient.doPost(url, inputParam);
		ObjectNode parseObject = (ObjectNode) JSONUtil.parserStr(new ObjectMapper(), doPost.getBodyStr());// 成功后会返回jobId

		if (parseObject.has("errors")) {
			if (parseObject.get("errors").asText().contains("DetachedApplicationRunner.tryExecuteJobs")) {// 不处理只报错误,其实是已经提交成功的,
				log.error("调用submitTask失败:", parseObject.get("errors").asText());
				return Result.getSuc();
			} else {
				return Result.getError(parseObject.get("errors").asText());
			}
		}
		return Result.getSuc();
	}

	public Result submitTask(String taskName, int parallelism, String savepointPath, Map params) {
		return submitTask(taskName, "tams_flink-sql-client-1.17.1.jar", parallelism, savepointPath, params);
	}

	public Result submitTask(String taskName) {
		return submitTask(taskName, 1, null, new HashMap<>());
	}

	public List findJobIds(String status) {
		String url = IOUtil.mergeFolderAndFilePath(this.jmUrl, "/jobs");
		HttpResult doGet = HttpClient.doGet(url);
		// "enum" : [ "INITIALIZING", "CREATED", "RUNNING", "FAILING", "FAILED",
		// "CANCELLING", "CANCELED", "FINISHED", "RESTARTING", "SUSPENDED",
		// "RECONCILING" ]
		ObjectNode retObj = null;
		ObjectMapper objectMapper = new ObjectMapper();
		try {
			retObj = (ObjectNode) JSONUtil.parserStr(objectMapper, doGet.getBodyStr());
		} catch (Exception e) {
			throw new ProjectExceptionRuntime(ExceptAll.Project_default, "找job失败", e);
		}
		ArrayNode res = (ArrayNode) retObj.get("jobs");
		List retlist = new ArrayList<>();
		for (int i = 0; i < res.size(); i++) {
			ObjectNode jsonObject = (ObjectNode) res.get(i);
			if (StringUtil.isNull(status) || status.equalsIgnoreCase(jsonObject.get("status").asText())) {
				retlist.add(jsonObject.get("id").asText());
			}
		}
		return retlist;
	}

	public Map findJobNames(String... status) {
		String url = IOUtil.mergeFolderAndFilePath(this.jmUrl, "/jobs/overview");
		HttpResult doGet = HttpClient.doGet(url);
		// "enum" : [ "INITIALIZING", "CREATED", "RUNNING", "FAILING", "FAILED",
		// "CANCELLING", "CANCELED", "FINISHED", "RESTARTING", "SUSPENDED",
		// "RECONCILING" ]
		ObjectNode retObj = null;
		try {
			retObj = (ObjectNode)JSONUtil.parserStr(new ObjectMapper(), doGet.getBodyStr());
		} catch (Exception e) {
			throw new ProjectExceptionRuntime(ExceptAll.Project_default, "找job失败", e);
		}
		ArrayNode res =(ArrayNode) retObj.get("jobs");
		Map retmap = new HashMap<>();
		for (int i = 0; i < res.size(); i++) {
			ObjectNode jsonObject = (ObjectNode)res.get(i);
			if (StringUtil.isNull(status) || ArrayUtils.contains(status, jsonObject.get("state").asText())) {
				retmap.put(jsonObject.get("name").asText(), jsonObject.get("state").asText());
			}
		}
		return retmap;
	}

	// 找到运行中或重启中(已部署)的任务
	public Map findDeployJobNames() {
		return findJobNames(new String[] { "RUNNING", "RESTARTING" });
	}

	// L:总槽数 R:可用槽数
	public Pair flindSlotInfo() {
		String url = IOUtil.mergeFolderAndFilePath(this.jmUrl, "/overview");
		HttpResult doGet = HttpClient.doGet(url);
		ObjectNode retObj = null;
		try {
			retObj = JSONUtil.parserStr(new ObjectMapper(), doGet.getBodyStr()) ;
		} catch (Exception e) {
			throw new ProjectExceptionRuntime(ExceptAll.Project_default, "找job失败", e);
		}
		return Pair.of(retObj.get("slots-total").asInt(), retObj.get("slots-available").asInt());
	}

	public Result cancelTask(String jobId) {
		HttpResult doPatch = HttpClient
				.doPatch(IOUtil.mergeFolderAndFilePath(this.jmUrl, String.format("/jobs/%s?mode=cancel", jobId)));
		ObjectNode parseObject=JSONUtil.parserStr(new ObjectMapper(), doPatch.getBodyStr());
		if (parseObject.isEmpty()) {
			return Result.getSuc();
		} else {
			return Result.getError(parseObject.get("errors").asText());
		}
	}

	// 已运行的job数
	public int hasRunningJobs() {
		List runjobs = findJobIds("RUNNING");
		return runjobs.size();
	}

	/***
	 * sucess retObjs[0] 为取消的jobid
	 */
	public Result cancelTaskFrist() {
		List runjobs = findJobIds("RUNNING");
		if (CollectionUtils.isEmpty(runjobs)) {
			return Result.getError("没有任务任务");
		}
		Result cancelTask = cancelTask(runjobs.get(0));
		if (cancelTask.isSuc()) {
			cancelTask.setRetObjs(runjobs.get(0));
		}
		return cancelTask;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy