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

com.alibaba.schedulerx.worker.util.JobProcessorUtil Maven / Gradle / Ivy

There is a newer version: 1.12.2
Show newest version
package com.alibaba.schedulerx.worker.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;

import com.alibaba.schedulerx.common.MyClassLoader;
import com.alibaba.schedulerx.common.domain.JobType;
import com.alibaba.schedulerx.common.domain.K8sJobXAttrs;
import com.alibaba.schedulerx.common.util.JsonUtil;
import com.alibaba.schedulerx.common.util.ReflectionUtil;
import com.alibaba.schedulerx.worker.SchedulerxWorker;
import com.alibaba.schedulerx.worker.domain.JavaProcessorProfile;
import com.alibaba.schedulerx.worker.domain.JobContext;
import com.alibaba.schedulerx.worker.log.LogFactory;
import com.alibaba.schedulerx.worker.log.Logger;
import com.alibaba.schedulerx.worker.processor.JavaProcessor;
import com.alibaba.schedulerx.worker.processor.JobProcessor;
import com.alibaba.schedulerx.worker.processor.JobProcessorRepository;
import com.alibaba.schedulerx.worker.processor.ProcessorFactory;

import org.apache.commons.lang.StringUtils;

/**
 *
 * @author xiaomeng.hxm
 */
public class JobProcessorUtil {
    
    private static final Logger LOGGER = LogFactory.getLogger(JobProcessorUtil.class);
    
    public static JobProcessor getJobProcessor(JobContext context) throws Exception {
        if (JobType.JAVA.getKey().equalsIgnoreCase(context.getJobType())) {
            return JobProcessorUtil.getJavaProcessor(context.getContent());
        } else if (JobType.XXLJOB.getKey().equalsIgnoreCase(context.getJobType())) {
            return JobProcessorUtil.getXxlJobProcessor(context.getContent());
        } else if (JobType.K8S.getKey().equalsIgnoreCase(context.getJobType())) {
            K8sJobXAttrs xAttrs = JsonUtil.fromJson(context.getXAttrs(), K8sJobXAttrs.class);
            return ProcessorFactory.create(context.getJobType() + "_" + xAttrs.getResource());
        } else {
            return ProcessorFactory.create(context);
        }
    }

    /**
     * 判断是否未指定类型
     * @param className
     * @param clazz
     * @return
     * @throws Exception
     */
    public static Boolean checkJavaProcessor(String className, Class clazz) throws Exception {
        int beanIdIndex = className.indexOf(":");
        if (beanIdIndex > 0) {
            className = className.substring(0, beanIdIndex);
        }
        Class javaProcessorClass = null;
        if (SchedulerxWorker.CUSTOMER_CLASS_LOADER == null) {
            javaProcessorClass = clazz.getClassLoader().loadClass(className);
        } else {
            javaProcessorClass = SchedulerxWorker.CUSTOMER_CLASS_LOADER.loadClass(className);
        }
        return clazz.isAssignableFrom(javaProcessorClass);
    }

    public static JobProcessor getJavaProcessor(String content) throws Exception {
        JobProcessor jobProcessor;
        JavaProcessorProfile profile = JsonUtil.fromJson(content, JavaProcessorProfile.class);
        //如果没有配置jarUrl,表示用户和用户应用在同一个进程中,直接从当前进程中获取
        if (profile.getJarUrl() == null || profile.getJarUrl().isEmpty()) {
            if (SpringContext.context != null) {
                try {
                    jobProcessor = SpringContext.getBean(profile.getClassName(), SchedulerxWorker.CUSTOMER_CLASS_LOADER);
                } catch (Exception e) {
                    LOGGER.warn("Spring bean not found.", e);
                    throw new RuntimeException("Spring bean not found. Can not found bean by Class="+profile.getClassName());
//                    jobProcessor = initSpringJobProcessor(profile.getClassName());
                }
            } else {
                jobProcessor = ReflectionUtil.getInstanceByClassName(profile.getClassName(), SchedulerxWorker.CUSTOMER_CLASS_LOADER);
            }
        } else {
            String jarUrl = profile.getJarUrl();
            String jarFilePath = jarUrl;
            @SuppressWarnings("resource")
            MyClassLoader classLoader = new MyClassLoader(new URL[] {}, Thread.currentThread()
                .getContextClassLoader());
            if (jarUrl.startsWith("file:")) {
                // jar包存在本地
                jarFilePath = jarUrl.substring("file:".length());
            } else if (jarUrl.startsWith("http:")) {
                // 这里目前主要是支持oss上传
                jarFilePath = FileDownloader.httpDownload(jarUrl);
            } else if (jarUrl.startsWith("hdfs:")) {
                //TODO 比如可以把jar包上传到hdfs上
            }

            File jarFile = new File(jarFilePath);
            if (!jarFile.exists()) {
                throw new IOException(jarFilePath + "is not existed!");
            }
            classLoader.addJar(jarFile.toURI().toURL());
            if (SpringContext.context != null) {
                jobProcessor = SpringContext.getBean(profile.getClassName(), classLoader);
            } else {
                Class clazz = classLoader.loadClass(profile.getClassName());
                jobProcessor = (JavaProcessor)ReflectionUtil.newInstanceWithoutCache(clazz);
            }
        }
        return jobProcessor;
    }
    
    /**
     * 兼容1.0用法,如果jobProcessor不是bean,反射filed去springcontext里获取同名的bean
     * @param className
     * @return
     * @throws ClassNotFoundException
     */
    private static JobProcessor initSpringJobProcessor(String className) throws Exception {
        JobProcessor jobProcessor = ReflectionUtil.getInstanceByClassName(className, SchedulerxWorker.CUSTOMER_CLASS_LOADER);
        /** 填充字段 */
        Field[] fields = jobProcessor.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            String fieldName = fields[i].getName();
            Object object = null;
            try {
                object = SpringContext.getBeanByName(fieldName);
            } catch (Throwable e) {
                LOGGER.warn("initSpringJobProcessor field not found"
                        + ", jobProcessor:" + className
                        + ", fieldName:" + fieldName, e);
            }
            if (object != null) {
                try {
                    fields[i].set(jobProcessor, object);
                } catch (Throwable e) {
                    LOGGER.error("initSpringJobProcessor field set error"
                            + ", jobProcessor:" + className
                            + ", fieldName:" + fieldName
                            + ", object:" + object, e);
                    continue;
                }
                LOGGER.info("initSpringJobProcessor set field successfully"
                        + ", jobProcessor:" + className
                        + ", fieldName:" + fieldName);
            }
        }
        return jobProcessor;
    }
    
    public static JobProcessor getXxlJobProcessor(String content) throws Exception {
        JavaProcessorProfile profile = JsonUtil.fromJson(content, JavaProcessorProfile.class);
        return JobProcessorRepository.loadJobProcessor(profile.getJobHandler());
    }

    /**
     * 获取配置的类名
     * @param content
     * @return
     * @throws Exception
     */
    public static String getSimpleClassName(String content) {
        JavaProcessorProfile profile = JsonUtil.fromJson(content, JavaProcessorProfile.class);
        if (profile.getJarUrl() == null || profile.getJarUrl().isEmpty()) {
            String className = profile.getClassName();
            if (StringUtils.isNotBlank(className)) {
                int beanIdIndex = className.indexOf(":");
                if (beanIdIndex > 0) {
                    className = className.substring(0, beanIdIndex);
                }
                if (className.contains(".")) {
                    className = StringUtils.substringAfterLast(className, ".");
                }
            }
            return className;
        }
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy