|
|
@@ -1,134 +0,0 @@
|
|
|
-/*
|
|
|
- * Copyright (c) 2018-2025, hnqz All rights reserved.
|
|
|
- *
|
|
|
- * Redistribution and use in source and binary forms, with or without
|
|
|
- * modification, are permitted provided that the following conditions are met:
|
|
|
- *
|
|
|
- * Redistributions of source code must retain the above copyright notice,
|
|
|
- * this list of conditions and the following disclaimer.
|
|
|
- * Redistributions in binary form must reproduce the above copyright
|
|
|
- * notice, this list of conditions and the following disclaimer in the
|
|
|
- * documentation and/or other materials provided with the distribution.
|
|
|
- * Neither the name of the pig4cloud.com developer nor the names of its
|
|
|
- * contributors may be used to endorse or promote products derived from
|
|
|
- * this software without specific prior written permission.
|
|
|
- * Author: hnqz
|
|
|
- */
|
|
|
-
|
|
|
-package net.yyc.quartz.util;
|
|
|
-
|
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
-import cn.hutool.http.HttpRequest;
|
|
|
-import cn.hutool.http.HttpUtil;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-import net.yyc.common.core.constant.CommonConstants;
|
|
|
-import net.yyc.common.core.constant.SecurityConstants;
|
|
|
-import net.yyc.quartz.entity.SysJob;
|
|
|
-import net.yyc.quartz.exception.TaskException;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.cloud.client.ServiceInstance;
|
|
|
-import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
-
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
-/**
|
|
|
- * 定时任务 REST 反射实现
|
|
|
- * 支持 service-name 模式(http://service-name/path)和 host:port 模式(http://host:port/path)
|
|
|
- *
|
|
|
- * @author 郑健楠
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-@Component
|
|
|
-public class RestTaskInvok implements ITaskInvok {
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private LoadBalancerClient loadBalancer;
|
|
|
-
|
|
|
- @Override
|
|
|
- public void invokMethod(SysJob sysJob) throws TaskException {
|
|
|
- try {
|
|
|
- String executePath = sysJob.getExecutePath();
|
|
|
- String resolvedUrl = resolveUrl(executePath);
|
|
|
-
|
|
|
- HttpRequest request = HttpUtil.createPost(resolvedUrl);
|
|
|
-
|
|
|
- // 租户 header
|
|
|
- if (sysJob.getTenantId() != null) {
|
|
|
- request.header(CommonConstants.TENANT_ID, sysJob.getTenantId().toString());
|
|
|
- }
|
|
|
-
|
|
|
- // 内部调用 header(绕过安全拦截器)
|
|
|
- request.header(SecurityConstants.FROM, SecurityConstants.FROM_IN);
|
|
|
-
|
|
|
- // 预留扩展 header(可由子类或配置覆盖)
|
|
|
- addExtraHeaders(request, sysJob);
|
|
|
-
|
|
|
- // 表单参数(params 对应 Controller @RequestParam)
|
|
|
- String methodParams = sysJob.getMethodParamsValue();
|
|
|
- if (StrUtil.isNotBlank(methodParams)) {
|
|
|
- Map<String, Object> formData = new HashMap<>();
|
|
|
- formData.put("params", methodParams);
|
|
|
- request.form(formData);
|
|
|
- }
|
|
|
-
|
|
|
- request.execute();
|
|
|
- log.debug("REST任务调用完成, url={}, params={}", resolvedUrl, methodParams);
|
|
|
- }
|
|
|
- catch (Exception e) {
|
|
|
- log.error("定时任务restTaskInvok异常,执行任务:{}", sysJob.getExecutePath());
|
|
|
- throw new TaskException("定时任务restTaskInvok业务执行失败,任务:" + sysJob.getExecutePath());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 解析 URL,支持两种模式:
|
|
|
- * 1. service-name 模式:http://service-name/path → 通过 LoadBalancer 解析为实际地址
|
|
|
- * 2. host:port 模式:http://host:port/path → 直接使用
|
|
|
- *
|
|
|
- * @param executePath 原始执行路径
|
|
|
- * @return 解析后的实际 URL
|
|
|
- */
|
|
|
- private String resolveUrl(String executePath) {
|
|
|
- if (executePath == null || !executePath.startsWith("http://")) {
|
|
|
- return executePath;
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- // 提取服务名和路径,例如: http://hnqz-upms-biz/admin/schedule-task/xxx
|
|
|
- String path = executePath.substring(7);
|
|
|
- int slashIndex = path.indexOf('/');
|
|
|
-
|
|
|
- if (slashIndex == -1) {
|
|
|
- return executePath;
|
|
|
- }
|
|
|
-
|
|
|
- String serviceName = path.substring(0, slashIndex);
|
|
|
- String servicePath = path.substring(slashIndex);
|
|
|
-
|
|
|
- // 尝试通过 LoadBalancer 解析服务名
|
|
|
- ServiceInstance instance = loadBalancer.choose(serviceName);
|
|
|
- if (instance != null) {
|
|
|
- return instance.getUri().toString() + servicePath;
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("服务名解析失败,使用原路径: {}", executePath, e);
|
|
|
- }
|
|
|
-
|
|
|
- // host:port 模式直接返回原路径
|
|
|
- return executePath;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 扩展点:子类可覆盖此方法添加额外的 header
|
|
|
- * 目前预留,未来可通过 SysJob 新增字段(如 invokeHeaders)实现动态配置
|
|
|
- *
|
|
|
- * @param request HTTP 请求
|
|
|
- * @param sysJob 任务实体
|
|
|
- */
|
|
|
- protected void addExtraHeaders(HttpRequest request, SysJob sysJob) {
|
|
|
- // 预留扩展点,可通过 sysJob.invokeHeaders 或配置文件动态添加 header
|
|
|
- }
|
|
|
-
|
|
|
-}
|