airflow系列之任务远程触发调用

1. 目标实现

我们希望通过消息队列或者API方式触发调用Airflow任务

2. 鉴权方式更改

通过如下命令查看

airflow config get-value api auth_backends

如果是session,在values.yaml中改为Basic Auth

airflowVersion: 2.5.3
defaultAirflowTag: 2.5.3.2
config:
  core:
    dags_folder: /opt/airflow/dags/repo/dags
    hostname_callable: airflow.utils.net.get_host_ip_address
  api:
    # 新增该配置
    auth_backends: airflow.api.auth.backend.basic_auth

3. 实现代码

/**
 * Airflow 工具类(使用 Basic Auth)
 */
public class AirflowUtils {
    private static final String AIRFLOW_URL = "https://airflow.sfxs.com";
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "公众号算法小生";

    /**
     * 触发 Airflow DAG 运行(使用 Basic Auth)
     * @param dagId      DAG 的 ID
     * @param conf       DAG 参数,JSON 格式
     * @param dagRunId   DAG 运行的唯一标识(可选,建议包含时间戳)
     * @return 触发结果(JSON 字符串)
     * @throws RuntimeException 如果请求失败
     */
    public static String runDag(String dagId, Map<String, Object> conf, String dagRunId) {
        String url = AIRFLOW_URL + "/api/v1/dags/" + dagId + "/dagRuns";

        // 设置 Basic Auth
        HttpHeaders headers = new HttpHeaders();
        String credentials = USERNAME + ":" + PASSWORD;
        String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
        headers.set("Authorization", "Basic " + encodedCredentials);
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 构造请求体
        Map<String, Object> body = new JSONObject();
        body.put("conf", conf);
        if (StringUtils.isNotBlank(dagRunId)) {
            body.put("dag_run_id", dagRunId);
        }

        try {
            return RequestUtils.postForEntity(url, body, headers);
        } catch (Exception e) {
            throw new RuntimeException("Failed to trigger DAG: " + dagId + ", Error: " + e.getMessage(), e);
        }
    }

    /**
     * 查询指定 DAG(使用 Basic Auth)
     *
     * @param dagId DAG 的 ID(精确匹配)
     * @return DAG 详情(JSON 字符串)
     * @throws RuntimeException 如果请求失败
     */
    public static String getDag(String dagId) {
        String url = AIRFLOW_URL + "/api/v1/dags";

        // 设置 Basic Auth
        HttpHeaders headers = new HttpHeaders();
        String credentials = USERNAME + ":" + PASSWORD;
        String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
        headers.set("Authorization", "Basic " + encodedCredentials);
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 设置查询参数 dag_id_pattern
        Map<String, String> params = new HashMap<>();
        params.put("dag_id_pattern", dagId);

        try {
            return RequestUtils.getContent(url, params, headers);
        } catch (Exception e) {
            throw new RuntimeException("Failed to get DAG: " + dagId + ", Error: " + e.getMessage(), e);
        }
    }
}

4. 测试验证

@Test
public void testAirflow() {
    //AirflowUtils.getDag("test_failure_notification");
    //AirflowUtils.runDag("test_failure_notification", null, null);
    String message = "{\"dag_id\":\"community_summary_dag\",\"conf\":{\"city\":\"临沂市\"}}";
    JSONObject jsonObject = JSONObject.parseObject(message);
    String dagId = jsonObject.getString("dag_id");
    JSONObject conf = jsonObject.getJSONObject("conf");

    if (StringUtils.isNotBlank(dagId)) {
        AirflowUtils.runDag(dagId, conf, null);
    }
}

OK, 运行后可以airflow中看到任务正在运行了~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法小生Đ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值