clszz) {
44 | if (proxyInstanceCache.containsKey(clszz)) {
45 | return (T) proxyInstanceCache.get(clszz);
46 | } else {
47 | proxyInstanceCache.put(clszz, context.getTaskProxy().getProxyInstance(clszz));
48 | }
49 | return (T) proxyInstanceCache.get(clszz);
50 | }
51 |
52 | /**
53 | * 根据Task实例名返回上下文,这是一个内部方法
54 | *
55 | * @param name
56 | * @return
57 | */
58 | public static TaskContext getTaskContext(String name) {
59 | return contextMap.get(name);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskBeanFactory.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | /**
4 | * 管理Task系统在执行任务时 ,任务对象所属实例获取方式.
5 | *
6 | * 如果你的项目使用类似ioc容器管理bean,你也可以自己实现该接口,从你的ioc容器中获取任务所属实例
7 | *
8 | * @author WangJun
9 | * @version 1.0 16/3/31
10 | */
11 | public interface TaskBeanFactory {
12 |
13 | T getBean(Class zclass);
14 |
15 | void newInstance(Class zClass,Object instance);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskClient.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | import com.peaceful.task.kernal.coding.TU;
4 |
5 | /**
6 | * Created by wangjun on 2016/9/30.
7 | */
8 | public interface TaskClient {
9 |
10 | void submit(TU tu);
11 | }
12 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskCoding.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | import com.peaceful.task.kernal.coding.TU;
4 | import com.peaceful.task.kernal.coding.TUR;
5 |
6 | import java.lang.reflect.Method;
7 |
8 | /**
9 | * 对异步类内方法调用的编码和解码
10 | *
11 | * 我们在调用Java方法时,每次调用其实就是产生一个Task,该接口是描述对调用信息的编码和解码操作
12 | *
13 | * @author WangJun
14 | * @version 1.0 16/1/12
15 | */
16 | public interface TaskCoding {
17 |
18 | /**
19 | * encoding将方法的调用转为可序列化的Task对象,最终目的是序列化成一串指令,可以存储到queue服务中,并支持可以反序列化,还原方法的调用信息
20 | *
21 | * @param zClass
22 | * @param method
23 | * @param args
24 | * @return SimpleTaskContext
25 | */
26 | TU encoding(Class zClass, Method method, Object[] args);
27 |
28 | /**
29 | * encoding方法将方法的调用动作编码为一个Task对象,Task对象序列化可以存储到queue服务中
30 | * decoding在根据queue中序列化的Task对象进行反序列化,主要操作包括类型转换,并包装为Runnable对象可供executor执行
31 | *
32 | * @param taskJson
33 | * @return Runnable的子对象TaskUnit, 可以被executor模块执行
34 | */
35 | TUR decoding(String taskJson);
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskContext.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | import com.peaceful.task.kernal.conf.TaskConfigOps;
4 |
5 | /**
6 | * Created by wangjun on 16-8-27.
7 | */
8 | public interface TaskContext {
9 |
10 | /**
11 | * @return 任务系统配置
12 | */
13 | TaskConfigOps getConfigOps();
14 | /**
15 | * @return 任务存储器
16 | */
17 | TaskQueue getTaskQueue();
18 |
19 | /**
20 | * @return 任务控制器
21 | */
22 | TaskController getTaskController();
23 |
24 | /**
25 | * @return 任务代理器
26 | */
27 | TaskProxy getTaskProxy();
28 |
29 | /**
30 | * @return 任务调度器
31 | */
32 | TaskDispatcher getTaskDispatcher();
33 |
34 | TaskBeanFactory getTaskBeanFactory();
35 |
36 | /**
37 | * @return 任务编码器
38 | */
39 | TaskCoding getTaskCoding();
40 |
41 | /**
42 | * @return 任务监视器
43 | */
44 | TaskMonitor getTaskMonitor();
45 |
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskController.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | import com.peaceful.task.kernal.conf.Executor;
4 | import com.peaceful.task.kernal.dispatch.TaskMeta;
5 |
6 | import java.util.*;
7 | import java.util.concurrent.ConcurrentHashMap;
8 |
9 | /**
10 | * 任务控制器:可以在这里查看所有的任务生产消费情况,通过特定的API干预任务的执行
11 | *
12 | * @author WangJun
13 | * @version 1.0 16/3/30
14 | */
15 | public interface TaskController {
16 |
17 | // 执行器列表
18 | List EXECUTOR_LIST = new ArrayList();
19 | // 可能已经完成的任务调度列表,此处必须使用线程安全的集合
20 | Map TASK_HISTORY_LIST = new ConcurrentHashMap();
21 | // 正在调度任务列表
22 | Map TASK_LIST = new ConcurrentHashMap();
23 |
24 | /**
25 | * 获取所有的任务,包括可能完成的任务与正在调度的任务
26 | *
27 | * @return
28 | */
29 | Collection findAllTasks();
30 |
31 | /**
32 | * 加入任务,如果任务已经存在,则更新任务的更新时间
33 | *
34 | * @param name
35 | */
36 | void insertTask(String name);
37 |
38 |
39 | void removeTask(TaskMeta task);
40 |
41 | /**
42 | * 获取本地可以调度的任务
43 | *
44 | * @return
45 | */
46 | Collection findNeedDispatchTasks();
47 |
48 | /**
49 | * 获取所有的任务执行器
50 | *
51 | * @return
52 | */
53 | Collection findAllExecutors();
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskDispatcher.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | /**
4 | * 任务调度器
5 | *
6 | * @author WangJun
7 | * @version 1.0 16/3/31
8 | */
9 | public interface TaskDispatcher {
10 |
11 | void dispatch();
12 | }
13 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskExecutor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | /**
4 | * 任务执行器
5 | *
6 | * @author WangJun
7 | * @version 1.0 16/1/11
8 | */
9 | public interface TaskExecutor {
10 |
11 | /**
12 | * 任务在某个节点被消费时,会被包装成一个Runnable对象,然后可以被Executor执行,或者直接调用起run方法执行
13 | *
14 | * @param task 一个实现Runnable接口的任务对象
15 | */
16 | void execute(Runnable task);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskModule.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | import com.google.inject.AbstractModule;
4 | import com.peaceful.task.kernal.client.TaskClientService;
5 | import com.peaceful.task.kernal.client.TaskProxyByCglib;
6 | import com.peaceful.task.kernal.coding.TaskCodingService;
7 | import com.peaceful.task.kernal.conf.TaskConfService;
8 | import com.peaceful.task.kernal.conf.TaskConfigOps;
9 | import com.peaceful.task.kernal.controller.RedisCloudTaskController;
10 | import com.peaceful.task.kernal.dispatch.TaskBeanFactoryImpl;
11 | import com.peaceful.task.kernal.dispatch.TaskDispatcherService;
12 | import com.peaceful.task.kernal.monitor.CloudTaskCountMonitor;
13 | import com.peaceful.task.kernal.queue.redis.RedisQueue;
14 |
15 | /**
16 | * Task Mail Module load
17 | *
18 | * Created by wangjun on 16-8-27.
19 | */
20 | public class TaskModule extends AbstractModule {
21 |
22 | @Override
23 | protected void configure() {
24 | // 初始化conf
25 | bind(TaskConfigOps.class).toInstance(TaskConfService.startUp());
26 | // 绑定任务控制器
27 | bind(TaskController.class).to(RedisCloudTaskController.class).asEagerSingleton();
28 | // 绑定任务编码器
29 | bind(TaskCoding.class).to(TaskCodingService.class).asEagerSingleton();
30 | // 绑定任务存储器
31 | bind(TaskQueue.class).to(RedisQueue.class).asEagerSingleton();
32 | // 绑定beanFactory
33 | bind(TaskBeanFactory.class).to(TaskBeanFactoryImpl.class).asEagerSingleton();
34 | // 装绑定任务监控器
35 | bind(TaskMonitor.class).to(CloudTaskCountMonitor.class).asEagerSingleton();
36 | // 绑定Task Client
37 | bind(TaskClient.class).to(TaskClientService.class).asEagerSingleton();
38 | // 绑定任务代理器
39 | bind(TaskProxy.class).to(TaskProxyByCglib.class).asEagerSingleton();
40 | // 绑定任务调度器
41 | bind(TaskDispatcher.class).to(TaskDispatcherService.class).asEagerSingleton();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskMonitor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | import com.peaceful.task.kernal.coding.TU;
4 |
5 | /**
6 | * @author WangJun
7 | * @version 1.0 16/3/31
8 | */
9 | public interface TaskMonitor {
10 |
11 | void produce(TU tu);
12 |
13 | void consume(TU tu);
14 |
15 | void exceptionIncr(String name);
16 | }
17 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskProxy.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | /**
4 | * Task任务的提交代理
5 | *
6 | * @author WangJun
7 | * @version 1.0 16/3/29
8 | */
9 | public interface TaskProxy {
10 |
11 | /**
12 | * 获取代理类实例
13 | *
14 | * @param zclass
15 | * @param
16 | * @return
17 | */
18 | T getProxyInstance(Class zclass);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/TaskQueue.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | /**
4 | * 用于存放任务的队列服务
5 | *
6 | * @author WangJun
7 | * @version 1.0 16/3/29
8 | */
9 | public interface TaskQueue {
10 |
11 | /**
12 | * 写入任务
13 | *
14 | * @param name 任务所在队列的名称
15 | * @param object 任务调用描述对象
16 | * @return true 表示写入成功 否则 return false
17 | */
18 | boolean push(String name, String object);
19 |
20 | /**
21 | * 从队列中取出一条任务
22 | *
23 | * @param name 任务所在队列的名称
24 | * @return 加入存在任务返回任务对象,否则返回null
25 | */
26 | String pop(String name);
27 |
28 | /**
29 | * 获取指定任务队列中含有任务的个数
30 | *
31 | * @param name 任务队列的名称
32 | * @return
33 | */
34 | long size(String name);
35 | }
36 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/annotation/Task.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * 任务单元描述:用于描述任务存放的队列和任务的执行器
10 | *
11 | * @author WangJun
12 | * @version 1.0 15/8/16
13 | * @since 1.6
14 | */
15 |
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @Target({ElementType.METHOD})
18 | public @interface Task {
19 |
20 | /**
21 | * 所存放队列
22 | *
23 | * @return
24 | */
25 | String value();
26 |
27 | /**
28 | * 执行者
29 | *
30 | * @return
31 | */
32 | String executor() default "default";
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/client/TaskClientService.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.client;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.alibaba.fastjson.serializer.SerializerFeature;
5 | import com.google.inject.Inject;
6 | import com.peaceful.task.kernal.TaskClient;
7 | import com.peaceful.task.kernal.TaskController;
8 | import com.peaceful.task.kernal.TaskMonitor;
9 | import com.peaceful.task.kernal.TaskQueue;
10 | import com.peaceful.task.kernal.coding.TU;
11 | import com.peaceful.task.kernal.conf.TaskConfigOps;
12 | import com.peaceful.task.kernal.helper.TaskLog;
13 |
14 | /**
15 | * Created by wangjun on 2016/9/30.
16 | */
17 | public class TaskClientService implements TaskClient {
18 |
19 | @Inject
20 | TaskConfigOps ops;
21 | @Inject
22 | TaskQueue queue;
23 | @Inject
24 | private TaskController controller;
25 | @Inject
26 | private TaskMonitor monitor;
27 |
28 | @Override
29 | public void submit(TU tu) {
30 | //解决FastJson循环引用的问题
31 | SerializerFeature feature = SerializerFeature.DisableCircularReferenceDetect;
32 | tu.setSubmitTime(System.currentTimeMillis());
33 | String cmd = JSON.toJSONString(tu, feature);
34 | // 提交到队列服务
35 | queue.push(ops.name + "-" + tu.queueName, cmd);
36 | controller.insertTask(tu.queueName);
37 | monitor.produce(tu);
38 | TaskLog.SUBMIT_TASK.info("submit task: {}", tu);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/client/TaskProxyByCglib.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.client;
2 |
3 | import com.google.inject.Inject;
4 | import com.peaceful.task.kernal.*;
5 | import com.peaceful.task.kernal.coding.TU;
6 | import com.peaceful.task.kernal.conf.TaskConfigOps;
7 | import com.alibaba.fastjson.JSON;
8 | import com.alibaba.fastjson.serializer.SerializerFeature;
9 | import com.peaceful.common.util.ExceptionUtils;
10 | import com.peaceful.task.kernal.helper.TaskLog;
11 | import net.sf.cglib.proxy.Enhancer;
12 | import net.sf.cglib.proxy.InvocationHandler;
13 | import org.perf4j.StopWatch;
14 | import org.perf4j.slf4j.Slf4JStopWatch;
15 | import org.slf4j.Logger;
16 | import org.slf4j.LoggerFactory;
17 |
18 | import java.lang.reflect.Method;
19 |
20 | /**
21 | * 通过代理将方法调用编码成任务对象并序列化成json对象提交任务到任务队列中
22 | *
23 | * @author WangJun
24 | * @version 1.0 16/1/9
25 | */
26 | public class TaskProxyByCglib implements TaskProxy {
27 |
28 | private static Logger logger = LoggerFactory.getLogger(TaskProxyByCglib.class);
29 | @Inject
30 | private TaskClient client;
31 | @Inject
32 | private TaskCoding coding;
33 |
34 | @Override
35 | public T getProxyInstance(final Class tClass) {
36 | Enhancer enhancer = new Enhancer();
37 | enhancer.setSuperclass(tClass);
38 | enhancer.setCallback(new InvocationHandler() {
39 | @Override
40 | public Object invoke(Object proxy, Method method, Object[] args)
41 | throws Throwable {
42 | StopWatch watch = new Slf4JStopWatch();
43 | // 调用信息编码
44 | TU tu = coding.encoding(tClass, method, args);
45 | if (tu != null) {
46 | try {
47 | client.submit(tu);
48 | watch.stop("task.produce");
49 | watch.stop("task." + tu.queueName + ".produce");
50 | } catch (Exception e) {
51 | TaskLog.SUBMIT_TASK.error("task submit fail:{},cause:{}", tu.toString(), ExceptionUtils.getStackTrace(e));
52 | throw new RuntimeException("task submit fail:" + tu, e);
53 | }
54 | }
55 | return null;
56 | }
57 | });
58 | T t = (T) enhancer.create();
59 | return t;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/TU.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.peaceful.task.kernal.TaskCoding;
5 | import com.alibaba.fastjson.annotation.JSONField;
6 |
7 | import java.io.Serializable;
8 | import java.lang.reflect.Method;
9 |
10 | /**
11 | * 任务描述协议
12 | *
13 | * 每次方法的调用都是一个Task的生成,通过{@link TaskCoding#encoding(Class, Method, Object[])}可以把
14 | * 方法的调用指令信息编码为一个TU对象,支持状态序列化
15 | *
16 | * @author WangJun
17 | * @version 1.0 16/1/9
18 | */
19 | public class TU implements Serializable {
20 |
21 | // 任务创建时应生成一个唯一id,用于log跟踪
22 | public String id;
23 | // 任务单元存放队列位置
24 | public String queueName = "default";
25 | // 该任务单元的Class入口
26 | @JSONField(deserialize = true)
27 | public Class aclass;
28 | // 该任务单元的方法入口
29 | public String method;
30 | // 该任务单元的方法参数类星列表
31 | public Class[] parameterTypes;
32 | // 该任务单元的方法参数列表
33 | public Object[] args;
34 | // 任务最终的执行器
35 | public String executor = "default";
36 | // 任务协议版本
37 | public String version = "2.0";
38 | // 任务提交时间
39 | public long submitTime;
40 |
41 | public long getSubmitTime() {
42 | return submitTime;
43 | }
44 |
45 | public void setSubmitTime(long submitTime) {
46 | this.submitTime = submitTime;
47 | }
48 |
49 | public Class getAclass() {
50 | return aclass;
51 | }
52 |
53 | public void setAclass(Class aclass) {
54 | this.aclass = aclass;
55 | }
56 |
57 | public String getExecutor() {
58 | return executor;
59 | }
60 |
61 | public Object[] getArgs() {
62 | return args;
63 | }
64 |
65 | public void setArgs(Object[] args) {
66 | this.args = args;
67 | }
68 |
69 | public String getId() {
70 | return id;
71 | }
72 |
73 | public void setId(String id) {
74 | this.id = id;
75 | }
76 |
77 | public String getMethod() {
78 | return method;
79 | }
80 |
81 | public void setMethod(String method) {
82 | this.method = method;
83 | }
84 |
85 | public Class[] getParameterTypes() {
86 | return parameterTypes;
87 | }
88 |
89 | public void setParameterTypes(Class[] parameterTypes) {
90 | this.parameterTypes = parameterTypes;
91 | }
92 |
93 | public String getQueueName() {
94 | return queueName;
95 | }
96 |
97 | public void setQueueName(String queueName) {
98 | this.queueName = queueName;
99 | }
100 |
101 | public void setExecutor(String executor) {
102 | this.executor = executor;
103 | }
104 |
105 | @Override
106 | public String toString() {
107 | return id + " " + aclass.getSimpleName() + "." + method + " " + arrayToString(args);
108 | }
109 |
110 | private String arrayToString(Object[] args) {
111 | StringBuffer buffer = new StringBuffer();
112 | buffer.append("[");
113 | for (Object o : args) {
114 | buffer.append(JSON.toJSONString(o) + ",");
115 | }
116 | return buffer.substring(0, buffer.length() - 1) + "]";
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/TUR.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding;
2 |
3 | import com.google.common.base.Preconditions;
4 | import com.google.common.base.Throwables;
5 | import com.peaceful.task.kernal.TaskContext;
6 | import com.peaceful.task.kernal.helper.TaskLog;
7 | import org.apache.commons.lang3.exception.ExceptionUtils;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import java.lang.reflect.InvocationTargetException;
12 | import java.lang.reflect.Method;
13 | import java.lang.reflect.UndeclaredThrowableException;
14 |
15 | /**
16 | * TU协议解析
17 | *
18 | * 将TU协议解析,这将会被解析成Runnable对象,然后可以被Executor执行
19 | *
20 | * 任务执行异常处理
21 | *
22 | * 任务在执行时如果抛出异常,则会将异常转为运行期异常并向上进行传播
23 | *
24 | * @author WangJun
25 | * @version 1.0 16/1/12
26 | */
27 | public class TUR implements Runnable {
28 |
29 | // TU协议信息
30 | private TU tu;
31 | // Task Context
32 | public TaskContext context;
33 | // 生成TUR的时间
34 | public long createTime = System.currentTimeMillis();
35 | private Logger logger = LoggerFactory.getLogger(getClass());
36 |
37 | public TUR(TU tu) {
38 | this.tu = tu;
39 | }
40 |
41 | @Override
42 | public void run() {
43 | if (tu == null) return;
44 | // 获取调用方法
45 | Method method = null;
46 | try {
47 | method = tu.aclass.getMethod(tu.method, tu.parameterTypes);
48 | } catch (NoSuchMethodException e) {
49 | throw new RuntimeException("task execute error:task->" + tu.id + ", not found method " + tu.aclass.getSimpleName() + "." + tu.method + " cause:" + ExceptionUtils.getStackTrace(e));
50 | }
51 | // 获取调用bean
52 | Object bean = null;
53 | try {
54 | bean = context.getTaskBeanFactory().getBean(tu.aclass);
55 | } catch (Exception e) {
56 | throw new RuntimeException("task execute error:task->" + tu.id + " not found bean instance " + tu.aclass.getSimpleName() + "." + tu.method + " cause:" + ExceptionUtils.getStackTrace(e));
57 | }
58 | Preconditions.checkState(method != null, "execute task fail,Not Fount " + tu.aclass.getName() + "." + tu.method);
59 | Preconditions.checkState(bean != null, "execute task fail,Not Fount bean instance for " + tu.aclass.getName() + "." + tu.method);
60 | // 开始执行方法
61 | try {
62 | method.invoke(bean, tu.args);
63 | } catch (Exception e) {
64 | TaskLog.DISPATCH_TASK.error("task execute error:task->{},TaskSystem only log the exception but catch it,cause:{}",this,Throwables.getStackTraceAsString(unwrapThrowable(e)));
65 | Throwables.propagate(unwrapThrowable(e));
66 | }
67 | }
68 |
69 | public TU getTask() {
70 | return tu;
71 | }
72 |
73 | public static Throwable unwrapThrowable(Throwable wrapped) {
74 | Throwable unwrapped = wrapped;
75 |
76 | while(true) {
77 | while(!(unwrapped instanceof InvocationTargetException)) {
78 | if(!(unwrapped instanceof UndeclaredThrowableException)) {
79 | return unwrapped;
80 | }
81 |
82 | unwrapped = ((UndeclaredThrowableException)unwrapped).getUndeclaredThrowable();
83 | }
84 |
85 | unwrapped = ((InvocationTargetException)unwrapped).getTargetException();
86 | }
87 | }
88 |
89 | @Override
90 | public String toString() {
91 | return tu.id+"["+ tu.aclass.getSimpleName()+"."+tu.method+"]";
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/TaskCodingService.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.google.inject.Inject;
5 | import com.peaceful.common.util.ExceptionUtils;
6 | import com.peaceful.task.kernal.TaskCoding;
7 | import com.peaceful.task.kernal.annotation.Task;
8 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
9 | import com.peaceful.task.kernal.coding.decoding.Magic;
10 | import com.peaceful.task.kernal.coding.decoding.TypeAdapter;
11 | import com.peaceful.task.kernal.helper.IdGenerate;
12 | import org.apache.commons.lang3.StringUtils;
13 | import org.slf4j.Logger;
14 | import org.slf4j.LoggerFactory;
15 |
16 | import java.lang.reflect.Method;
17 |
18 | /**
19 | * @author WangJun
20 | * @version 1.0 16/1/9
21 | */
22 | public class TaskCodingService implements TaskCoding {
23 |
24 | private Logger logger = LoggerFactory.getLogger(getClass());
25 | @Inject
26 | private TypeAdapter typeAdapter;
27 | @Inject
28 | private Magic magic;
29 |
30 | /**
31 | * 把调用信息按TU协议进行编码
32 | * @param zClass
33 | * @param method
34 | * @param args
35 | * @return
36 | */
37 | public TU encoding(Class zClass, Method method, Object[] args) {
38 | if (method.getDeclaringClass() != Object.class) {
39 | TU tu = new TU();
40 | tu.setAclass(zClass);
41 | tu.setMethod(method.getName());
42 | tu.setParameterTypes(method.getParameterTypes());
43 | tu.setArgs(args);
44 | Task taskAno = method.getAnnotation(Task.class);
45 | if (taskAno == null) {
46 | tu.setQueueName(zClass.getSimpleName()+"."+method.getName());
47 | }else{
48 | tu.setQueueName(taskAno.value());
49 | tu.setExecutor(taskAno.executor());
50 | }
51 | tu.setId(IdGenerate.getNext(tu.queueName));
52 | return tu;
53 | }
54 | if (method.getReturnType().toString().equals("void")) {
55 | // ignore
56 | } else {
57 | logger.warn("TaskSystem suggested that do not have a return value");
58 | }
59 | return null;
60 | }
61 |
62 | /**
63 | * 解析TU协议为一个Runnable对象
64 | * @param taskJson
65 | * @return
66 | */
67 |
68 | public TUR decoding(String taskJson) {
69 | if (StringUtils.isEmpty(taskJson)) return null;
70 | TU tu = JSON.parseObject(taskJson, TU.class);
71 | if (tu.aclass == null) {
72 | logger.error("can't decoding the {} ,may be the task matched class object not in the jvm", taskJson);
73 | return null;
74 | }
75 | try {
76 | InvokeContext invokeContext = new InvokeContext(tu);
77 | TUR taskUnit = magic.go(typeAdapter.execute(invokeContext));
78 | return taskUnit;
79 | } catch (Exception e) {
80 | logger.error("decoding task id {}, method {} error {}", tu.id, tu.aclass.getSimpleName() + "." + tu.method, ExceptionUtils.getStackTrace(e));
81 | return null;
82 | }
83 | }
84 |
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/InvokeContext.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding;
2 |
3 |
4 | import com.peaceful.common.util.chain.BaseContext;
5 | import com.peaceful.common.util.chain.Context;
6 | import com.peaceful.task.kernal.coding.TU;
7 |
8 | import java.lang.reflect.Method;
9 | import java.lang.reflect.Type;
10 |
11 | /**
12 | * 调用信息上下文,每个任务单元都应该一个独立的调用上下文
13 | * 该类不是线程安全,为了保证安全,需要为每个任务单元创建一个上下文
14 | *
15 | * @author WangJun
16 | * @version 1.0 15/8/27
17 | * @since 1.6
18 | */
19 |
20 | public class InvokeContext extends BaseContext implements Context {
21 |
22 | public String id;
23 |
24 | // 调用类
25 | public Class aClass;
26 |
27 | // 调用方法
28 | public String methodName;
29 |
30 | // 参数类型列表
31 | public Class[] parameterTypes;
32 |
33 | // 获取实际参数类型,针对泛型问题进行解决
34 | public Type[] types;
35 |
36 | // 调用实际传参
37 | public Object[] args;
38 |
39 | // 解析参数到对应的类型
40 | public Object[] newArgs;
41 |
42 | public String executor;
43 |
44 | public String queueName;
45 |
46 | // 解析进度
47 | public int index;
48 |
49 | // 解析总进度
50 | public int length;
51 |
52 | // 任务提交时间
53 | public long submitTime;
54 |
55 | public Method method;
56 |
57 | // 利用Task2任务单元构造调用上下文信息
58 | public InvokeContext(TU task2) throws NoSuchMethodException {
59 | id = task2.id;
60 | queueName = task2.queueName;
61 | aClass = task2.aclass;
62 | methodName = task2.method;
63 | parameterTypes = task2.parameterTypes;
64 | args = task2.args;
65 | executor = task2.executor;
66 | length = args.length;
67 | newArgs = new Object[length];
68 | index = 0;
69 | submitTime = task2.getSubmitTime();
70 | method = aClass.getMethod(methodName, parameterTypes);
71 | types = method.getGenericParameterTypes();
72 | }
73 |
74 | public Type getCurrentParamType() {
75 | return types[index - 1];
76 | }
77 |
78 | public Object getCurrentArg() {
79 | return newArgs[index - 1];
80 | }
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/Magic.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding;
2 |
3 |
4 | import com.google.inject.Singleton;
5 | import com.peaceful.task.kernal.coding.TU;
6 | import com.peaceful.task.kernal.coding.TUR;
7 |
8 | /**
9 | * @author WangJun
10 | * @version 1.0 16/1/12
11 | */
12 | @Singleton
13 | public class Magic {
14 |
15 | public TUR go(InvokeContext invokeContext) {
16 | TU task02 = new TU();
17 | task02.id = invokeContext.id;
18 | task02.queueName = invokeContext.queueName;
19 | task02.aclass = invokeContext.aClass;
20 | task02.method = invokeContext.methodName;
21 | task02.args = invokeContext.newArgs;
22 | task02.parameterTypes = invokeContext.parameterTypes;
23 | task02.executor = invokeContext.executor;
24 | task02.submitTime = invokeContext.submitTime;
25 | TUR taskUnit = new TUR(task02);
26 | return taskUnit;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/NotSupportParamType.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding;
2 |
3 | import java.lang.reflect.Type;
4 |
5 | /**
6 | * @author WangJun
7 | * @version 1.0 15/8/28
8 | * @since 1.6
9 | */
10 |
11 | public class NotSupportParamType extends RuntimeException {
12 |
13 | public NotSupportParamType(Class zClass){
14 | super("not support paramType "+zClass);
15 | }
16 |
17 | public NotSupportParamType(Type type){
18 | super("not support paramType "+type);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/Parse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding;
2 |
3 |
4 | import com.peaceful.common.util.chain.Command;
5 |
6 | /**
7 | *
8 | * 参数解析
9 | *
10 | * @author WangJun
11 | * @version 1.0 15/8/27
12 | * @since 1.6
13 | */
14 |
15 | public interface Parse extends Command {
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/ParseChain.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding;
2 |
3 |
4 | import com.peaceful.common.util.chain.BaseChain;
5 |
6 | /**
7 | * @author WangJun
8 | * @version 1.0 15/8/27
9 | * @since 1.6
10 | */
11 |
12 | public class ParseChain extends BaseChain {
13 |
14 |
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/TypeAdapter.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding;
2 |
3 | import com.google.inject.Singleton;
4 | import com.peaceful.common.util.chain.Context;
5 | import com.peaceful.task.kernal.coding.decoding.impl.*;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | /**
10 | * 对Task进行解码,并包装成TaskUnit对象,提供给Executor执行
11 | *
12 | * @author WangJun
13 | * @version 1.0 15/8/28
14 | * @since 1.6
15 | */
16 | @Singleton
17 | public class TypeAdapter {
18 |
19 | Logger logger = LoggerFactory.getLogger(getClass());
20 |
21 | private static ParseChain parseChain;
22 |
23 | static {
24 | parseChain = new ParseChain();
25 | parseChain.addCommand(new NullParse());
26 | parseChain.addCommand(new EmptyParse());
27 | parseChain.addCommand(new PrimitiveParse());
28 | parseChain.addCommand(new StringParse());
29 | parseChain.addCommand(new IntegerParse());
30 | parseChain.addCommand(new BooleanParse());
31 | parseChain.addCommand(new LongParse());
32 | parseChain.addCommand(new DoubleParse());
33 | parseChain.addCommand(new ListParse());
34 | parseChain.addCommand(new MapParse());
35 | parseChain.addCommand(new SetParse());
36 | parseChain.addCommand(new UserDefinedParse());
37 | }
38 |
39 | public InvokeContext execute(Context context) throws Exception {
40 | InvokeContext invokeContext = (InvokeContext) context;
41 | for (int i = 0; i < invokeContext.length; i++) {
42 | if (parseChain.execute(invokeContext)) {
43 | logger.debug("{} param[{}] {} {}", invokeContext.aClass.getSimpleName()+"."+invokeContext.methodName,i,invokeContext.getCurrentParamType(), invokeContext.getCurrentArg());
44 | } else {
45 | throw new NotSupportParamType(invokeContext.getCurrentParamType());
46 | }
47 | }
48 | return invokeContext;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/BooleanParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 |
4 | import com.peaceful.common.util.chain.Context;
5 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
6 | import com.peaceful.task.kernal.coding.decoding.Parse;
7 |
8 | /**
9 | * Boolean类型参数解析
10 | *
11 | * @author WangJun
12 | * @version 1.0 15/8/27
13 | * @since 1.6
14 | */
15 |
16 | public class BooleanParse implements Parse {
17 |
18 | @Override
19 | public boolean execute(Context context) throws Exception {
20 | InvokeContext invokeContext = (InvokeContext) context;
21 | if (invokeContext.parameterTypes[invokeContext.index].equals(Boolean.class)) {
22 | invokeContext.newArgs[invokeContext.index] = Boolean.valueOf(invokeContext.args[invokeContext.index].toString());
23 | invokeContext.index++;
24 | return PROCESSING_COMPLETE;
25 | }
26 | return CONTINUE_PROCESSING;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/DoubleParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 |
4 | import com.peaceful.common.util.chain.Context;
5 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
6 | import com.peaceful.task.kernal.coding.decoding.Parse;
7 |
8 | /**
9 | * Double类型参数解析
10 | *
11 | * @author WangJun
12 | * @version 1.0 15/8/27
13 | * @since 1.6
14 | */
15 |
16 | public class DoubleParse implements Parse {
17 |
18 | @Override
19 | public boolean execute(Context context) throws Exception {
20 | InvokeContext invokeContext = (InvokeContext) context;
21 | if (invokeContext.parameterTypes[invokeContext.index].equals(Double.class)) {
22 | invokeContext.newArgs[invokeContext.index] = Double.valueOf(invokeContext.args[invokeContext.index].toString());
23 | invokeContext.index++;
24 | return PROCESSING_COMPLETE;
25 | }
26 | return CONTINUE_PROCESSING;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/EmptyParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 | import com.peaceful.common.util.chain.Context;
4 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
5 | import com.peaceful.task.kernal.coding.decoding.NotSupportParamType;
6 | import com.peaceful.task.kernal.coding.decoding.Parse;
7 |
8 | /**
9 | * 这里会验证所有不支持的参数类型,包括
10 | *
11 | * char(Character)
12 | * short(Short)
13 | * byte(Byte)
14 | * float(Float)
15 | *
16 | * 如果遇到这些参数类型,将会抛出 NotSupportParamType()
17 | *
18 | * @author WangJun
19 | * @version 1.0 15/8/28
20 | * @since 1.6
21 | */
22 |
23 | public class EmptyParse implements Parse {
24 |
25 | @Override
26 | public boolean execute(Context context) throws Exception {
27 | InvokeContext invokeContext = (InvokeContext) context;
28 | int index = invokeContext.index;
29 | boolean flag = false;
30 | Class zClass = invokeContext.parameterTypes[index];
31 | if (zClass.isPrimitive()) {
32 | if (zClass.equals(char.class)) {
33 | flag = true;
34 | } else if (zClass.equals(byte.class)) {
35 | flag = true;
36 | } else if (zClass.equals(float.class)) {
37 | flag = true;
38 | } else if (zClass.equals(short.class)) {
39 | flag = true;
40 | }
41 | } else {
42 | if (zClass.equals(Character.class)) {
43 | flag = true;
44 | } else if (zClass.equals(Byte.class)) {
45 | flag = true;
46 | } else if (zClass.equals(Float.class)) {
47 | flag = true;
48 | } else if (zClass.equals(Short.class)) {
49 | flag = true;
50 | }
51 | }
52 |
53 | if (flag) {
54 | invokeContext.newArgs[index] = null;
55 | invokeContext.index++;
56 | throw new NotSupportParamType(zClass);
57 | }
58 | return CONTINUE_PROCESSING;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/IntegerParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 |
4 | import com.peaceful.common.util.chain.Context;
5 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
6 | import com.peaceful.task.kernal.coding.decoding.Parse;
7 |
8 | /**
9 | * Integer类型参数解析
10 | *
11 | * @author WangJun
12 | * @version 1.0 15/8/27
13 | * @since 1.6
14 | */
15 |
16 | public class IntegerParse implements Parse {
17 |
18 | @Override
19 | public boolean execute(Context context) throws Exception {
20 | InvokeContext invokeContext = (InvokeContext) context;
21 | if (invokeContext.parameterTypes[invokeContext.index].equals(Integer.class)) {
22 | invokeContext.newArgs[invokeContext.index] = Integer.valueOf(invokeContext.args[invokeContext.index].toString());
23 | invokeContext.index++;
24 | return PROCESSING_COMPLETE;
25 | }
26 | return CONTINUE_PROCESSING;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/ListParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.alibaba.fastjson.JSONArray;
5 | import com.peaceful.common.util.chain.Context;
6 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
7 | import com.peaceful.task.kernal.coding.decoding.Parse;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * List类型参数解析
13 | *
14 | * @author WangJun
15 | * @version 1.0 15/8/27
16 | * @since 1.6
17 | */
18 |
19 | public class ListParse implements Parse {
20 |
21 | @Override
22 | public boolean execute(Context context) throws Exception {
23 | InvokeContext invokeContext = (InvokeContext) context;
24 | if (invokeContext.parameterTypes[invokeContext.index].equals(List.class)) {
25 | JSONArray object = (JSONArray) invokeContext.args[invokeContext.index];
26 | invokeContext.newArgs[invokeContext.index] = JSON.parseObject(object.toJSONString(), invokeContext.types[invokeContext.index]);
27 | invokeContext.index++;
28 | return PROCESSING_COMPLETE;
29 | }
30 | return CONTINUE_PROCESSING;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/LongParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 |
4 | import com.peaceful.common.util.chain.Context;
5 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
6 | import com.peaceful.task.kernal.coding.decoding.Parse;
7 |
8 | /**
9 | * Long类型参数解析
10 | *
11 | * @author WangJun
12 | * @version 1.0 15/8/27
13 | * @since 1.6
14 | */
15 |
16 | public class LongParse implements Parse {
17 |
18 | @Override
19 | public boolean execute(Context context) throws Exception {
20 | InvokeContext invokeContext = (InvokeContext) context;
21 | if (invokeContext.parameterTypes[invokeContext.index].equals(Long.class)) {
22 | invokeContext.newArgs[invokeContext.index] = Long.valueOf(invokeContext.args[invokeContext.index].toString());
23 | invokeContext.index++;
24 | return PROCESSING_COMPLETE;
25 | }
26 | return CONTINUE_PROCESSING;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/MapParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.alibaba.fastjson.JSONObject;
5 | import com.peaceful.common.util.chain.Context;
6 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
7 | import com.peaceful.task.kernal.coding.decoding.Parse;
8 |
9 | import java.util.Map;
10 |
11 | /**
12 | * Map类型参数解析
13 | *
14 | * @author WangJun
15 | * @version 1.0 15/8/27
16 | * @since 1.6
17 | */
18 |
19 | public class MapParse implements Parse {
20 |
21 | @Override
22 | public boolean execute(Context context) throws Exception {
23 | InvokeContext invokeContext = (InvokeContext) context;
24 | if (invokeContext.parameterTypes[invokeContext.index].equals(Map.class)) {
25 | JSONObject object = (JSONObject) invokeContext.args[invokeContext.index];
26 | invokeContext.newArgs[invokeContext.index] = JSON.parseObject(object.toJSONString(), invokeContext.types[invokeContext.index]);
27 | invokeContext.index++;
28 | return PROCESSING_COMPLETE;
29 | }
30 | return CONTINUE_PROCESSING;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/NullParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 | import com.peaceful.common.util.chain.Context;
4 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
5 | import com.peaceful.task.kernal.coding.decoding.Parse;
6 |
7 | /**
8 | * Null类型参数解析,该解析器的位置应该放置第一位
9 | *
10 | * @author WangJun
11 | * @version 1.0 15/8/27
12 | * @since 1.6
13 | */
14 |
15 | public class NullParse implements Parse {
16 |
17 | @Override
18 | public boolean execute(Context context) throws Exception {
19 | InvokeContext invokeContext = (InvokeContext) context;
20 | if (invokeContext.args[invokeContext.index] == null) {
21 | invokeContext.newArgs[invokeContext.index] = null;
22 | invokeContext.index++;
23 | return PROCESSING_COMPLETE;
24 | }
25 | return CONTINUE_PROCESSING;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/PrimitiveParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 | import com.peaceful.common.util.chain.Context;
4 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
5 | import com.peaceful.task.kernal.coding.decoding.Parse;
6 |
7 | /**
8 | * Primitive类型参数解析 {@link Class#isPrimitive()}
9 | *
10 | * 下面这些类型虽然也是Primitive类型,但这些类型的解析,需要单独考虑,请注意{@link EmptyParse}
11 | * char
12 | * short
13 | * byte
14 | * float
15 | *
16 | * @author WangJun
17 | * @version 1.0 15/8/27
18 | * @since 1.6
19 | */
20 |
21 | public class PrimitiveParse implements Parse {
22 |
23 | @Override
24 | public boolean execute(Context context) throws Exception {
25 | InvokeContext invokeContext = (InvokeContext) context;
26 | if (invokeContext.parameterTypes[invokeContext.index].isPrimitive()) {
27 | invokeContext.newArgs[invokeContext.index] = invokeContext.args[invokeContext.index];
28 | invokeContext.index++;
29 | return PROCESSING_COMPLETE;
30 | }
31 | return CONTINUE_PROCESSING;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/SetParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.alibaba.fastjson.JSONArray;
5 | import com.peaceful.common.util.chain.Context;
6 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
7 | import com.peaceful.task.kernal.coding.decoding.Parse;
8 |
9 | import java.util.Set;
10 |
11 | /**
12 | * Long类型参数解析
13 | *
14 | * @author WangJun
15 | * @version 1.0 15/8/27
16 | * @since 1.6
17 | */
18 |
19 | public class SetParse implements Parse {
20 |
21 | @Override
22 | public boolean execute(Context context) throws Exception {
23 | InvokeContext invokeContext = (InvokeContext) context;
24 | if (invokeContext.parameterTypes[invokeContext.index].equals(Set.class)) {
25 | JSONArray object = (JSONArray) invokeContext.args[invokeContext.index];
26 | invokeContext.newArgs[invokeContext.index] = JSON.parseObject(object.toJSONString(), invokeContext.types[invokeContext.index]);
27 | invokeContext.index++;
28 | return PROCESSING_COMPLETE;
29 | }
30 | return CONTINUE_PROCESSING;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/StringParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 | import com.peaceful.common.util.chain.Context;
4 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
5 | import com.peaceful.task.kernal.coding.decoding.Parse;
6 |
7 | /**
8 | * Long类型参数解析
9 | *
10 | * @author WangJun
11 | * @version 1.0 15/8/27
12 | * @since 1.6
13 | */
14 |
15 | public class StringParse implements Parse {
16 |
17 | @Override
18 | public boolean execute(Context context) throws Exception {
19 | InvokeContext invokeContext = (InvokeContext) context;
20 | if (invokeContext.parameterTypes[invokeContext.index].equals(String.class)) {
21 | invokeContext.newArgs[invokeContext.index] = invokeContext.args[invokeContext.index];
22 | invokeContext.index++;
23 | return PROCESSING_COMPLETE;
24 | }
25 | return CONTINUE_PROCESSING;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/coding/decoding/impl/UserDefinedParse.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.coding.decoding.impl;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.alibaba.fastjson.JSONObject;
5 | import com.peaceful.common.util.chain.Context;
6 | import com.peaceful.task.kernal.coding.decoding.InvokeContext;
7 | import com.peaceful.task.kernal.coding.decoding.Parse;
8 |
9 | /**
10 | * @author WangJun
11 | * @version 1.0 15/8/27
12 | * @since 1.6
13 | */
14 |
15 | public class UserDefinedParse implements Parse {
16 |
17 | @Override
18 | public boolean execute(Context context) throws Exception {
19 | InvokeContext invokeContext = (InvokeContext) context;
20 | if (invokeContext.parameterTypes[invokeContext.index].isPrimitive()) {
21 |
22 | } else {
23 | JSONObject object = (JSONObject) invokeContext.args[invokeContext.index];
24 | invokeContext.newArgs[invokeContext.index] = JSON.parseObject(object.toJSONString(), invokeContext.parameterTypes[invokeContext.index]);
25 | invokeContext.index++;
26 | return PROCESSING_COMPLETE;
27 | }
28 | return CONTINUE_PROCESSING;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/conf/Executor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.conf;
2 |
3 | /**
4 | * 任务执行器
5 | *
6 | * Created by wangjun on 16/1/12.
7 | */
8 | public class Executor {
9 |
10 | // 执行器的名称
11 | public String name;
12 | // 执行器的完整类名称
13 | public String implementation;
14 | // 执行器对应的Class对象
15 | public java.lang.Class> Class;
16 | }
17 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/conf/ExecutorsConf.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.conf;
2 |
3 | import com.google.common.util.concurrent.ThreadFactoryBuilder;
4 |
5 | import java.util.concurrent.Executors;
6 | import java.util.concurrent.ScheduledExecutorService;
7 | import java.util.concurrent.ThreadFactory;
8 |
9 | /**
10 | * Created by wangjun on 16/8/28.
11 | */
12 | public class ExecutorsConf {
13 |
14 |
15 | private final static ThreadFactory threadFactoryBuilder = new ThreadFactoryBuilder()
16 | .setNameFormat("task-commons-%d")
17 | .setDaemon(true)
18 | .build();
19 | public static final ScheduledExecutorService SINGLE_THREAD_SCHEDULED = Executors.newSingleThreadScheduledExecutor(threadFactoryBuilder);
20 | }
21 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/conf/TaskConfigOps.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.conf;
2 |
3 | import com.google.inject.Singleton;
4 | import com.peaceful.task.kernal.helper.NetHelper;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | /**
10 | * Created by wangjun on 16/1/10.
11 | */
12 | @Singleton
13 | public class TaskConfigOps {
14 |
15 | // 当前系统版本号
16 | public static final String VERSION = "2.6";
17 | // 系统名称,用于区分多个系统
18 | public String name = null;
19 | //系统启动模式,client or server
20 | public String bootMode = "client";
21 | // TaskQueue 任务队列实现
22 | public String queue;
23 | // BeanFactory实现
24 | public String beanFactory;
25 | // test or product
26 | public String developMode = "product";
27 | //executor module conf
28 | public ExecutorConfigOps executorConfigOps = new ExecutorConfigOps();
29 | public class ExecutorConfigOps {
30 | public List executorNodeList = new ArrayList();
31 |
32 | @Override
33 | public String toString() {
34 | StringBuffer buffer = new StringBuffer();
35 | buffer.append("[").append("\n");
36 | for (Executor executor:executorNodeList){
37 | buffer.append("\t").append(executor.name).append("->").append(executor.implementation).append("\n");
38 | }
39 | buffer.append("]");
40 | return buffer.toString();
41 | }
42 | }
43 |
44 | @Override
45 | public String toString() {
46 | return "Task Kernal["+VERSION+"]"+ " Name["+name+"]";
47 | }
48 |
49 | public String detail(){
50 | StringBuffer buffer = new StringBuffer();
51 | buffer.append("----------------------Task Kernal--------------------------------------").append("\n");
52 | buffer.append(toString()).append("\n");
53 | buffer.append("hostname:").append(NetHelper.getHostname()).append("\n");
54 | buffer.append("task.boot.mode:").append(bootMode).append("\n");
55 | buffer.append("task.queue.impl:").append(queue).append("\n");
56 | buffer.append("task.bean.factory.impl:").append(beanFactory).append("\n");
57 | buffer.append("task.executor.list:").append(executorConfigOps).append("\n");
58 | buffer.append("-----------------------------------------------------------------------");
59 | return buffer.toString();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/controller/CloudController.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.controller;
2 |
3 | import com.peaceful.task.kernal.TaskController;
4 | import com.peaceful.task.kernal.helper.Node;
5 |
6 | import java.util.Collection;
7 | import java.util.Map;
8 | import java.util.concurrent.ConcurrentHashMap;
9 |
10 | /**
11 | * @author WangJun
12 | * @version 1.0 16/3/31
13 | */
14 | public interface CloudController extends TaskController {
15 |
16 |
17 | Map NODE_MAP = new ConcurrentHashMap();
18 |
19 | /**
20 | * 本地和云端进行信息同步
21 | */
22 | void sync();
23 |
24 |
25 | /**
26 | * 获取集群中所有的服务节点
27 | *
28 | * @return
29 | */
30 | Collection findNodes();
31 |
32 |
33 |
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/NoBlockAutoConsumer.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch;
2 |
3 | import akka.actor.ActorSystem;
4 | import akka.actor.Props;
5 | import com.google.common.util.concurrent.AbstractIdleService;
6 | import com.google.inject.Inject;
7 | import com.google.inject.Singleton;
8 | import com.peaceful.task.kernal.Task;
9 | import com.peaceful.task.kernal.coding.TUR;
10 | import com.peaceful.task.kernal.conf.TaskConfigOps;
11 | import com.peaceful.task.kernal.dispatch.actor.DispatchManagerActor;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | import java.util.HashMap;
16 | import java.util.Map;
17 |
18 | /**
19 | * 无阻塞自动任务调度模块
20 | * Created by wangjun on 16-8-27.
21 | */
22 | @Singleton
23 | public class NoBlockAutoConsumer extends AbstractIdleService {
24 |
25 | private ActorSystem system;
26 | private Logger logger = LoggerFactory.getLogger(getClass());
27 | private static Map systemMap = new HashMap();
28 |
29 | @Inject
30 | private TaskConfigOps ops;
31 |
32 | // 接收来自TaskDispatchService的消息,并将消息直接传入到ExecutorsManagerActor
33 | public void tell(TUR tur) {
34 | system.actorSelection("/user/dispatcher/executors").tell(tur,system.actorFor("/user/dispatcher/"));
35 | }
36 |
37 | protected void startUp() throws Exception {
38 | system = ActorSystem.create(ops.name);
39 | // 创建actor系统的top actor,所有actor都要求从这里继承下去
40 | system.actorOf(Props.create(DispatchManagerActor.class, Task.getTaskContext(ops.name)), "dispatcher");
41 | systemMap.put(ops.name,system);
42 | logger.info("no block auto dispatch service start...");
43 | }
44 |
45 | protected void shutDown() throws Exception {
46 | if (!system.isTerminated()) {
47 | system.shutdown();
48 | }
49 | }
50 |
51 | public static ActorSystem getSystem(String name){
52 | return systemMap.get(name);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/PullTask.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch;
2 |
3 | import com.google.common.base.Throwables;
4 | import com.peaceful.task.kernal.*;
5 | import com.peaceful.task.kernal.coding.TUR;
6 | import com.peaceful.task.kernal.conf.TaskConfigOps;
7 | import org.apache.commons.lang3.StringUtils;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | /**
12 | * Created by wangjun on 16/1/12.
13 | */
14 | public class PullTask {
15 |
16 | private TaskConfigOps ops;
17 | private TaskMonitor monitor;
18 | private TaskController controller;
19 | private TaskCoding coding;
20 | private TaskQueue queue;
21 | private Logger logger = LoggerFactory.getLogger(getClass());
22 |
23 | public static PullTask get(TaskContext context) {
24 | PullTask pullTask = new PullTask();
25 | pullTask.ops = context.getConfigOps();
26 | pullTask.monitor = context.getTaskMonitor();
27 | pullTask.controller = context.getTaskController();
28 | pullTask.coding = context.getTaskCoding();
29 | pullTask.queue = context.getTaskQueue();
30 | return pullTask;
31 | }
32 |
33 | /**
34 | * 从队列服务中取出task指令
35 | *
36 | * @param queueName
37 | * @return
38 | */
39 | public TUR next(String queueName) {
40 | try {
41 | if (controller.findNeedDispatchTasks().contains(new TaskMeta(queueName))) {
42 | String taskJson = queue.pop(ops.name + "-" + queueName);
43 | if (StringUtils.isNoneEmpty(taskJson)) {
44 | TUR taskUnit = coding.decoding(taskJson);
45 | monitor.consume(taskUnit.getTask());
46 | return taskUnit;
47 | }
48 | }
49 | } catch (Exception e) {
50 | // 关键性日志
51 | logger.error("can't get next task from {},cause:{}", queueName, Throwables.getStackTraceAsString(e));
52 | }
53 | return null;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/TaskBeanFactoryImpl.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch;
2 |
3 | import com.peaceful.task.kernal.TaskBeanFactory;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.util.Map;
8 | import java.util.concurrent.ConcurrentHashMap;
9 |
10 | /**
11 | * @author WangJun
12 | * @version 1.0 16/3/31
13 | */
14 | public class TaskBeanFactoryImpl implements TaskBeanFactory {
15 |
16 | // 任务对象实例容器
17 | private final static Map ASYNC_TASK_INSTANCE = new ConcurrentHashMap();
18 |
19 | private final static Logger LOGGER = LoggerFactory.getLogger(TaskBeanFactoryImpl.class);
20 |
21 | @Override
22 | public T getBean(Class zclass) {
23 | if (ASYNC_TASK_INSTANCE.containsKey(zclass)) {
24 | return (T) ASYNC_TASK_INSTANCE.get(zclass);
25 | } else {
26 | try {
27 | Object instance = zclass.newInstance();
28 | LOGGER.debug("auto create {} instance OK...", zclass.getName());
29 | ASYNC_TASK_INSTANCE.put(zclass, instance);
30 | return (T) instance;
31 | } catch (InstantiationException e) {
32 | LOGGER.error("Error:{}", e);
33 | } catch (IllegalAccessException e) {
34 | LOGGER.error("Error:{}", e);
35 | }
36 | }
37 | return null;
38 | }
39 |
40 | @Override
41 | public void newInstance(Class zClass,Object instance) {
42 | if (!ASYNC_TASK_INSTANCE.containsKey(zClass)) {
43 | ASYNC_TASK_INSTANCE.put(zClass, instance);
44 | LOGGER.info("new instance info ,insert instance suc {}", zClass);
45 | } else {
46 | LOGGER.warn("new instance warn , instance {} is exist", zClass);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/TaskDispatcherService.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch;
2 |
3 | import com.google.common.base.Throwables;
4 | import com.google.common.util.concurrent.AbstractScheduledService;
5 | import com.google.inject.Inject;
6 | import com.peaceful.task.kernal.Task;
7 | import com.peaceful.task.kernal.TaskController;
8 | import com.peaceful.task.kernal.TaskDispatcher;
9 | import com.peaceful.task.kernal.coding.TUR;
10 | import com.peaceful.task.kernal.conf.TaskConfigOps;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | import java.util.Collection;
15 | import java.util.concurrent.TimeUnit;
16 |
17 | /**
18 | * 定时从任务队列中拉取任务消息
19 | * Created by wangjun on 16-8-27.
20 | */
21 | public class TaskDispatcherService extends AbstractScheduledService implements TaskDispatcher {
22 |
23 | @Inject
24 | private TaskController controller;
25 | @Inject
26 | private NoBlockAutoConsumer noBlockAutoDispatch;
27 | @Inject
28 | private TaskConfigOps ops;
29 | private PullTask pullTask;
30 | private Logger logger = LoggerFactory.getLogger(getClass());
31 |
32 | @Inject
33 | public TaskDispatcherService() {
34 | this.startAsync();
35 | }
36 |
37 | @Override
38 | public void dispatch() {
39 | try {
40 | if (noBlockAutoDispatch.state() == State.NEW || noBlockAutoDispatch.state() == State.STARTING) {
41 | noBlockAutoDispatch.startAsync();
42 | noBlockAutoDispatch.awaitRunning();
43 | pullTask = PullTask.get(Task.getTaskContext(ops.name));
44 | }
45 | // 从controller中获取需要调度的任务
46 | Collection taskMetas = controller.findNeedDispatchTasks();
47 | if (taskMetas == null && taskMetas.isEmpty()) {
48 | return;
49 | }
50 | for (TaskMeta meta : taskMetas) {
51 | TUR unit = pullTask.next(meta.name);
52 | if (unit != null) {
53 | if (noBlockAutoDispatch.isRunning()) {
54 | noBlockAutoDispatch.tell(unit);
55 | } else {
56 | logger.error("dispatcher service not running,current state->{},task->{} ", noBlockAutoDispatch.state(),unit);
57 | }
58 | }
59 | }
60 | } catch (Exception e) {
61 | // dispatch 失败,需要记录日志,关键性日志
62 | logger.error("dispatch exception:{}", Throwables.getStackTraceAsString(e));
63 | }
64 | }
65 |
66 | @Override
67 | protected void runOneIteration() throws Exception {
68 | dispatch();
69 | }
70 |
71 | @Override
72 | protected Scheduler scheduler() {
73 | return Scheduler.newFixedRateSchedule(1, 1, TimeUnit.SECONDS);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/TaskMeta.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch;
2 |
3 | /**
4 | * 任务队列描述
5 | *
6 | * @author WangJun
7 | * @version 1.0 16/3/30
8 | */
9 | public class TaskMeta {
10 |
11 | public String name;// 队列名
12 | public String desc;// 描述
13 | public String state = "OK"; // 状态 OK 可以被所有机器调用 hostname 只能被某台机器调用 isLock 不允许被调用
14 | public long reserve = 0;
15 | public long createTime;// 任务创建时间
16 | public long updateTime;// 任务最近更新时间
17 | public boolean expire;// 是否已经过期
18 |
19 | public TaskMeta() {
20 |
21 | }
22 |
23 | public TaskMeta(String name) {
24 | this.name = name;
25 | state = "OK";
26 | }
27 |
28 |
29 | @Override
30 | public boolean equals(Object o) {
31 | if (this == o) return true;
32 | if (!(o instanceof TaskMeta)) return false;
33 | TaskMeta task = (TaskMeta) o;
34 | return name != null ? name.equals(task.name) : task.name == null;
35 | }
36 |
37 | @Override
38 | public int hashCode() {
39 | return name != null ? name.hashCode() : 0;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/actor/DispatchManagerActor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.actor;
2 |
3 | import akka.actor.*;
4 | import akka.event.DiagnosticLoggingAdapter;
5 | import akka.event.Logging;
6 | import akka.japi.Function;
7 | import com.peaceful.task.kernal.TaskContext;
8 | import com.peaceful.task.kernal.helper.GetNextTaskException;
9 | import scala.concurrent.duration.Duration;
10 |
11 | /**
12 | * 其只负责ExecutorsManagerActor的运行情况
13 | *
14 | * @author WangJun
15 | * @version 1.0 16/1/12
16 | */
17 | public class DispatchManagerActor extends UntypedActor {
18 |
19 | DiagnosticLoggingAdapter log = Logging.getLogger(this);
20 |
21 | private TaskContext context;
22 |
23 | public DispatchManagerActor(TaskContext context) {
24 | this.context = context;
25 | }
26 |
27 | @Override
28 | public void preStart() throws Exception {
29 | getContext().actorOf(Props.create(ExecutorsManagerActor.class, context), "executors");
30 | // public actor 作为其它需要利用到actor地方的监管者
31 | getContext().actorOf(Props.create(PublicActor.class), "public");
32 | super.preStart();
33 | }
34 |
35 | @Override
36 | public void onReceive(Object message) throws Exception {
37 | log.info("{}", message);
38 | unhandled(message);
39 |
40 | }
41 |
42 |
43 | /**
44 | * top actor supervisor is restart
45 | *
46 | * @return
47 | */
48 | @Override
49 | public SupervisorStrategy supervisorStrategy() {
50 | final SupervisorStrategy strategy = new OneForOneStrategy(
51 | 10, Duration.create("1 minute"), new Function() {
52 | @Override
53 | public SupervisorStrategy.Directive apply(Throwable t) {
54 | if (t instanceof GetNextTaskException) {
55 | log.error("{} receive message [{}] from child,resume", getSelf().path(), t.getMessage());
56 | return SupervisorStrategy.resume();
57 | }
58 | log.error("{} supervisor will restart child actor exception {}", self().path().name(), t);
59 | return SupervisorStrategy.restart();
60 | }
61 | });
62 | return strategy;
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/actor/ExecutorSupervisionActor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.actor;
2 |
3 | import akka.actor.UntypedActor;
4 | import akka.event.DiagnosticLoggingAdapter;
5 | import akka.event.Logging;
6 | import com.peaceful.task.kernal.TaskContext;
7 | import com.peaceful.task.kernal.TaskExecutor;
8 | import com.peaceful.task.kernal.coding.TUR;
9 | import com.peaceful.task.kernal.dispatch.actor.msg.DecorateTask;
10 |
11 | /**
12 | * executor监控者
13 | *
14 | * Created by wangjun on 16/1/12.
15 | */
16 | public class ExecutorSupervisionActor extends UntypedActor {
17 |
18 | // // TODO: 16/1/12 测试executor失败的情况
19 | private TaskExecutor taskExecutor;
20 | private TaskContext context;
21 | DiagnosticLoggingAdapter log = Logging.getLogger(this);
22 |
23 | public ExecutorSupervisionActor(TaskExecutor taskExecutor, TaskContext context) {
24 | this.taskExecutor = taskExecutor;
25 | this.context = context;
26 | }
27 |
28 | @Override
29 | public void onReceive(Object o) throws Exception {
30 | if (o instanceof TUR) {
31 | TUR taskUnit = (TUR) o;
32 | DecorateTask decorate = new DecorateTask(context, taskUnit, self());
33 | taskExecutor.execute(decorate);
34 | } else {
35 | unhandled(o);
36 | }
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/actor/PublicActor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.actor;
2 |
3 | import akka.actor.OneForOneStrategy;
4 | import akka.actor.Props;
5 | import akka.actor.SupervisorStrategy;
6 | import akka.actor.UntypedActor;
7 | import akka.event.DiagnosticLoggingAdapter;
8 | import akka.event.Logging;
9 | import akka.japi.Function;
10 | import scala.concurrent.duration.Duration;
11 |
12 | /**
13 | * 如果需要扩展,请以该public actor为root 向下创建actor
14 | * supervisor strategy: restart
15 | *
16 | * Created by wangjun on 16/1/13.
17 | */
18 | public class PublicActor extends UntypedActor {
19 |
20 | DiagnosticLoggingAdapter log = Logging.getLogger(this);
21 |
22 | @Override
23 | public void preStart() throws Exception {
24 | getContext().actorOf(Props.create(TaskRouterActor.class), "taskDispatch");
25 | super.preStart();
26 | }
27 |
28 | @Override
29 | public void onReceive(Object message) throws Exception {
30 | log.info("public unhandle message {}", message);
31 | unhandled(message);
32 | }
33 |
34 | /**
35 | * top actor supervisor is restart
36 | *
37 | * @return
38 | */
39 | @Override
40 | public SupervisorStrategy supervisorStrategy() {
41 | SupervisorStrategy strategy = new OneForOneStrategy(
42 | 10, Duration.create("1 minute"), new Function() {
43 | @Override
44 | public SupervisorStrategy.Directive apply(Throwable t) {
45 | log.error("{} supervisor will resume child actor exception {}", self().path().name(), t);
46 | return SupervisorStrategy.restart();
47 | }
48 | });
49 | return strategy;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/actor/TaskRouterActor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.actor;
2 |
3 | import akka.actor.*;
4 | import akka.event.DiagnosticLoggingAdapter;
5 | import akka.event.Logging;
6 | import akka.japi.Function;
7 | import akka.routing.ActorRefRoutee;
8 | import akka.routing.RoundRobinRoutingLogic;
9 | import akka.routing.Routee;
10 | import akka.routing.Router;
11 | import com.peaceful.task.kernal.dispatch.actor.msg.DecorateTask;
12 | import scala.concurrent.duration.Duration;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | /**
18 | * 任务调度路由中心
19 | *
20 | * 路由中心分发任务方式有两种:
21 | * 第一,由系统的任务存储和调度监管委派,路由在把该任务分发给某个适合的actor,这种分发称之为强制分发,目的是为了路由中心和worker不会在一个任务队列上循环
22 | * 使每个任务队列都有机会被调度
23 | * 第二,由路由中心和worker之间的内部协调分发,这种分发称之为协调分发,目的是为了路由中心和某个actor之间维持一种近长连接的状态,快速循环调度
24 | *
25 | *
26 | * 调度中心模块的router采用轮询的方式调用worker
27 | * Created by wangjun on 15/3/11.
28 | */
29 | public class TaskRouterActor extends UntypedActor {
30 |
31 | final DiagnosticLoggingAdapter log = Logging.getLogger(this);
32 | Router router;
33 |
34 |
35 | {
36 | List routees = new ArrayList();
37 | for (int i = 0; i < 8; i++) {
38 | ActorRef r = getContext().actorOf(Props.create(WorkerActor.class), "worker-" + i);
39 | getContext().watch(r);
40 | routees.add(new ActorRefRoutee(r));
41 | }
42 | router = new Router(new RoundRobinRoutingLogic(), routees);
43 | }
44 |
45 |
46 | @Override
47 | public void onReceive(Object msg) throws Exception {
48 | if (msg instanceof DecorateTask) {
49 | router.route(msg, getSelf());
50 | }
51 | else if (msg instanceof Terminated) {
52 | router = router.removeRoutee(((Terminated) msg).actor());
53 | ActorRef r = getContext().actorOf(Props.create(WorkerActor.class), ((Terminated) msg).actor().path().name());
54 | getContext().watch(r);
55 | router = router.addRoutee(new ActorRefRoutee(r));
56 | }
57 | }
58 |
59 |
60 | /**
61 | * worker 监管策略 restart
62 | * 如果worker在执行过程中发生异常,目前只是简单的尝试重启worker,如果1分钟内尝试10次还是不可以执行,则停止尝试
63 | *
64 | * @return
65 | */
66 | @Override
67 | public SupervisorStrategy supervisorStrategy() {
68 | SupervisorStrategy strategy = new OneForOneStrategy(
69 | 10, Duration.create("1 minute"), new Function() {
70 | @Override
71 | public SupervisorStrategy.Directive apply(Throwable t) {
72 | log.error("supervise worker found error {},cause {}", t, t.getCause());
73 | return SupervisorStrategy.restart();
74 | }
75 | });
76 | return strategy;
77 | }
78 | }
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/actor/WorkerActor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.actor;
2 |
3 | import akka.actor.UntypedActor;
4 |
5 | /**
6 | * @author WangJun
7 | * @version 1.0 16/1/11
8 | */
9 | public class WorkerActor extends UntypedActor {
10 |
11 | @Override
12 | public void onReceive(Object message) throws Exception {
13 | Runnable task = (Runnable) message;
14 | task.run();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/actor/msg/DecorateTask.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.actor.msg;
2 |
3 | import akka.actor.ActorRef;
4 | import akka.actor.ActorSystem;
5 | import akka.event.Logging;
6 | import akka.event.LoggingAdapter;
7 | import com.google.common.base.Throwables;
8 | import com.peaceful.task.kernal.TaskContext;
9 | import com.peaceful.task.kernal.coding.TUR;
10 | import com.peaceful.task.kernal.dispatch.NoBlockAutoConsumer;
11 | import org.perf4j.StopWatch;
12 | import org.perf4j.slf4j.Slf4JStopWatch;
13 |
14 | /**
15 | * 装饰TaskUnit,使其在完成任务后通知executor dispatch
16 | *
17 | * Created by wangjun on 16/1/15.
18 | */
19 | public class DecorateTask implements Runnable {
20 |
21 | TUR taskUnit;
22 | ActorRef executorActor;
23 | private final LoggingAdapter log;
24 | private ActorSystem system;
25 |
26 | public DecorateTask(TaskContext context, TUR taskUnit, ActorRef execuotActor) {
27 | this.taskUnit = taskUnit;
28 | this.taskUnit.context = context;
29 | this.executorActor = execuotActor;
30 | this.system = NoBlockAutoConsumer.getSystem(context.getConfigOps().name);
31 | log = Logging.getLogger(system, DecorateTask.class);
32 | }
33 |
34 | @Override
35 | public void run() {
36 | TaskCompleted completed = new TaskCompleted(taskUnit);
37 | completed.startTime = System.currentTimeMillis();
38 | StopWatch watch = new Slf4JStopWatch();
39 | try {
40 | taskUnit.run();
41 | watch.stop("task.consume");
42 | watch.stop("task." + taskUnit.getTask().queueName + ".consume");
43 | } catch (Exception e) {
44 | watch.stop("task.consume.error");
45 | completed.isHasException = true;
46 | Throwables.propagate(e);
47 | } finally {
48 | completed.completeTime = System.currentTimeMillis();
49 | // 通知所属ExecutorActor任务完成
50 | system.actorSelection("/user/dispatcher/executors").tell(completed, executorActor);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/actor/msg/TaskCompleted.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.actor.msg;
2 |
3 |
4 | import com.peaceful.task.kernal.coding.TUR;
5 |
6 | /**
7 | * confirm task unit completed msg
8 | *
9 | * Created by wangjun on 16/1/12.
10 | */
11 | public class TaskCompleted {
12 |
13 | // task id
14 | public String id;
15 | // QUEUE of task
16 | public String queue;
17 | // execute of task
18 | public String executor;
19 | // task 提交时间
20 | public long submitTime;
21 | // task 拉取时间
22 | public long createTime;
23 | // task 开始时间
24 | public long startTime;
25 | // task 完成时间
26 | public long completeTime;
27 |
28 | public boolean isHasException;
29 |
30 | public TaskCompleted(TUR taskUnit) {
31 | this.id = taskUnit.getTask().id;
32 | this.queue = taskUnit.getTask().queueName;
33 | this.executor = taskUnit.getTask().executor;
34 | this.createTime = taskUnit.createTime;
35 | this.submitTime = taskUnit.getTask().getSubmitTime();
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/executor/JUCTaskExecutor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.executor;
2 |
3 | import com.peaceful.task.kernal.TaskExecutor;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.util.concurrent.ExecutorService;
8 | import java.util.concurrent.Executors;
9 |
10 | /**
11 | * Created by wangjun on 16/1/12.
12 | */
13 | public class JUCTaskExecutor implements TaskExecutor {
14 |
15 | Logger logger = LoggerFactory.getLogger(getClass());
16 | ExecutorService executorService = Executors.newFixedThreadPool(8);
17 |
18 | @Override
19 | public void execute(Runnable task) {
20 | executorService.submit(task);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/dispatch/executor/SimpleTaskExecutor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.dispatch.executor;
2 |
3 |
4 | import com.peaceful.task.kernal.TaskExecutor;
5 |
6 | /**
7 | * Created by wangjun on 16/1/13.
8 | */
9 | public class SimpleTaskExecutor implements TaskExecutor {
10 |
11 | @Override
12 | public void execute(Runnable task) {
13 | task.run();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/helper/GetNextTaskException.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.helper;
2 |
3 | /**
4 | * @author WangJun
5 | * @version 1.0 16/4/2
6 | */
7 | public class GetNextTaskException extends RuntimeException {
8 |
9 | public GetNextTaskException(String msg){
10 | super(msg);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/helper/IdGenerate.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.helper;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.net.InetAddress;
7 | import java.net.UnknownHostException;
8 |
9 | /**
10 | * 唯一id生成器
11 | *
12 | * @author WangJun
13 | * @version 1.0 15/8/16
14 | * @since 1.6
15 | */
16 |
17 | public class IdGenerate {
18 |
19 | static Logger logger = LoggerFactory.getLogger(IdGenerate.class);
20 |
21 | /**
22 | * 通过nanoTime作为唯一ID
23 | *
24 | * @return
25 | */
26 | public static String getNext() {
27 | String hostName = "null";
28 | try {
29 | hostName = InetAddress.getLocalHost().getHostName();
30 | } catch (UnknownHostException e) {
31 | logger.error("id generate error {}", e);
32 | }
33 | return String.valueOf(hostName + "-" + System.currentTimeMillis());
34 | }
35 |
36 | public static String getNext(String prefix) {
37 | return prefix + "-" + getNext();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/helper/IllegalTaskStateException.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.helper;
2 |
3 | /**
4 | * @author WangJun
5 | * @version 1.0 16/4/1
6 | */
7 | public class IllegalTaskStateException extends RuntimeException{
8 |
9 | public IllegalTaskStateException(String msg){
10 | super(msg);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/helper/NetHelper.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.helper;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.io.IOException;
7 | import java.net.InetAddress;
8 | import java.net.UnknownHostException;
9 |
10 | /**
11 | * Created by wangjun on 16/1/18.
12 | */
13 | public class NetHelper {
14 |
15 | static Logger logger = LoggerFactory.getLogger(NetHelper.class);
16 |
17 | public static String getIp() {
18 | try {
19 | return InetAddress.getLocalHost().getHostAddress();
20 | } catch (UnknownHostException e) {
21 | logger.error("Error:{} ", e);
22 | }
23 | return "Empty";
24 | }
25 |
26 |
27 | public static String getHostname() {
28 | try {
29 | return InetAddress.getLocalHost().getHostName();
30 | } catch (UnknownHostException e) {
31 | e.printStackTrace();
32 | logger.error("Error: {}", e);
33 | }
34 | return "Empty";
35 | }
36 |
37 | public static boolean ping(String ip, int seconds) {
38 | int timeOut = seconds;
39 | try {
40 | return InetAddress.getByName(ip).isReachable(timeOut);
41 | } catch (IOException e) {
42 | logger.error("Error: {}", e);
43 | return false;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/helper/Node.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.helper;
2 |
3 | /**
4 | * SimpleTaskContext 集群节点信息
5 | *
6 | * @author WangJun
7 | * @version 1.0 16/1/11
8 | */
9 | public class Node {
10 |
11 | // 节点hostname
12 | public String hostName;
13 | // 节点ip
14 | public String ip;
15 | // 节点启动模式
16 | public String mode;
17 | // 节点状态
18 | public String state;
19 | // 节点启动时间
20 | public long startTime;
21 | // 节点信息更新时间
22 | public long updateTime;
23 |
24 | public Node() {
25 | }
26 |
27 | public Node(String hostName, String ip) {
28 | this.hostName = hostName;
29 | this.ip = ip;
30 | this.state = "OK";
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/helper/ServiceCenter.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.helper;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 | import java.util.Set;
6 |
7 | /**
8 | * 服务中心用于管理TaskSystem运行期的状态信息
9 | *
10 | * @author WangJun
11 | * @version 1.0 16/1/11
12 | */
13 | public interface ServiceCenter {
14 |
15 |
16 | /**
17 | * 获取系统的名字
18 | *
19 | * @return
20 | */
21 | String getSystemName();
22 |
23 | /**
24 | * 获取集群中所有的服务节点
25 | *
26 | * @return
27 | */
28 | List getAllServiceNode();
29 |
30 | /**
31 | * 获取master节点
32 | *
33 | * @return
34 | */
35 | String getMaster();
36 |
37 |
38 | /**
39 | * 加入当前节点到服务中心
40 | */
41 | void addServiceNode();
42 |
43 | /**
44 | * 移除当前节点
45 | */
46 | void removeServiceNode();
47 |
48 | /**
49 | * 移除指定服务节点
50 | *
51 | * @param hostName
52 | */
53 | void removeServiceNode(String hostName);
54 |
55 | /**
56 | * 选举master节点
57 | *
58 | * @return
59 | */
60 | Node electMasterNode();
61 |
62 | /**
63 | * 当前节点是否是master节点
64 | *
65 | * @return
66 | */
67 | boolean isMasterNode();
68 |
69 | boolean addRouter(String queueName, String hostname);
70 |
71 | boolean removeRouter(String queueName);
72 |
73 | Map getRouterTable();
74 |
75 |
76 | /**
77 | * 添加 focused task
78 | *
79 | * @param queueName
80 | * @return
81 | */
82 | boolean addFocusedTask(String queueName);
83 |
84 | // Map updateQueue();
85 |
86 | // void updateQueueState();
87 |
88 |
89 | /**
90 | * 清除focused task 列表
91 | *
92 | * @return
93 | */
94 | boolean clearFocusedTask();
95 |
96 | /**
97 | * 添加 flexible task
98 | *
99 | * @param queueName
100 | * @return
101 | */
102 | boolean addFlexibleTask(String queueName);
103 |
104 | /**
105 | * 获取focused task 列表
106 | *
107 | * @return
108 | */
109 | Set getAllFocusedTask();
110 |
111 | /**
112 | * 获取flexible task 列表
113 | *
114 | * @return
115 | */
116 | Set getAllFlexibleTask();
117 |
118 | /**
119 | * 停止指定队列的调度
120 | *
121 | * @param queueName
122 | * @return
123 | */
124 | boolean lockQueue(String queueName);
125 |
126 | boolean queueIsLock(String queueName);
127 |
128 | /**
129 | * 打开指定队列的调度
130 | *
131 | * @param queueName
132 | * @return
133 | */
134 | boolean openQueueLock(String queueName);
135 |
136 | /**
137 | * 停止指定节点的调度
138 | *
139 | * @param hostname
140 | * @return
141 | */
142 | boolean lockNode(String hostname);
143 |
144 | boolean nodeIsLock(String hostname);
145 |
146 | /**
147 | * 打开指定节点的调度
148 | *
149 | * @param hostname
150 | * @return
151 | */
152 | boolean openNodeLock(String hostname);
153 |
154 |
155 |
156 | }
157 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/helper/TaskLog.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.helper;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | /**
7 | * 系统关键性日志
8 | * Created by wangjun on 16/8/29.
9 | */
10 | public class TaskLog {
11 |
12 | public static final Logger SUBMIT_TASK = LoggerFactory.getLogger("task.kernal.log.client.submit");
13 | public static final Logger DISPATCH_TASK = LoggerFactory.getLogger("task.kernal.log.dispatch");
14 | public static final Logger COMPLETE_TASK = LoggerFactory.getLogger("task.kernal.log.dispatch.complete");
15 | public static final Logger ERROR_TASK = LoggerFactory.getLogger("task.kernal.log.dispatch.complete");
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/monitor/CloudTaskCountMonitor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.monitor;
2 |
3 | import com.google.inject.Inject;
4 | import com.peaceful.task.kernal.conf.TaskConfigOps;
5 | import com.peaceful.common.redis.service.Redis;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.util.concurrent.Executors;
10 | import java.util.concurrent.ScheduledExecutorService;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | /**
14 | * 同步本地记录的任务提交和消费次数到一个集中的地方。在一个中心记录生产次数和消费次数的目的是
15 | *
16 | * 1. 合并各个节点的生产消费次数
17 | * 2. 监控系统可以查询该中心的数据,做实时系统监控
18 | *
19 | * 目前实现的版本是集中地方是Redis。
20 | *
21 | * @author WangJun
22 | * @version 1.0 16/4/4
23 | */
24 | public class CloudTaskCountMonitor extends LocalTaskCountMonitor {
25 |
26 | private static String CLOUD_TASK_PRODUCE_COUNT;
27 | private static String CLOUD_TASK_CONSUME_COUNT;
28 | private static String CLOUD_TASK_FAIL_COUNT;
29 | Logger logger = LoggerFactory.getLogger(getClass());
30 |
31 | @Inject
32 | public CloudTaskCountMonitor(TaskConfigOps ops) {
33 | CLOUD_TASK_PRODUCE_COUNT = "TASK-" + ops.name + "-PRODUCE-COUNT-MONITOR";
34 | CLOUD_TASK_CONSUME_COUNT = "TASK-" + ops.name + "-CONSUME-COUNT-MONITOR";
35 | CLOUD_TASK_FAIL_COUNT = "TASK-" + ops.name + "-EXCEPTION-COUNT-MONITOR";
36 | ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
37 | executorService.scheduleAtFixedRate(new CloudMonitorSync(), 6, 6, TimeUnit.SECONDS);
38 | }
39 |
40 | private class CloudMonitorSync implements Runnable {
41 |
42 | @Override
43 | public void run() {
44 | try {
45 | // 定时清空本地记录数据,将数据同步记录到Redis中
46 | for (String queue : TASK_PRODUCT_COUNT.keySet()) {
47 | Redis.cmd().hincrBy(CLOUD_TASK_PRODUCE_COUNT, queue, TASK_PRODUCT_COUNT.get(queue).getAndSet(0));
48 | }
49 | for (String queue : TASK_CONSUME_COUNT.keySet()) {
50 | Redis.cmd().hincrBy(CLOUD_TASK_CONSUME_COUNT, queue, TASK_CONSUME_COUNT.get(queue).getAndSet(0));
51 | }
52 | for (String queue : TASK_FAIL_COUNT.keySet()) {
53 | Redis.cmd().hincrBy(CLOUD_TASK_FAIL_COUNT, queue, TASK_FAIL_COUNT.get(queue).getAndSet(0));
54 | }
55 | } catch (Exception e) {
56 | logger.error("upload task submit & consume count error", e);
57 | }
58 | }
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/monitor/LocalTaskCountMonitor.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.monitor;
2 |
3 | import com.peaceful.task.kernal.TaskMonitor;
4 | import com.peaceful.task.kernal.coding.TU;
5 |
6 | import java.util.Map;
7 | import java.util.concurrent.ConcurrentHashMap;
8 | import java.util.concurrent.atomic.AtomicLong;
9 |
10 | /**
11 | * 记录本地机器的任务提交次数和消费次数
12 | *
13 | * @author WangJun
14 | * @version 1.0 16/4/4
15 | */
16 | public class LocalTaskCountMonitor implements TaskMonitor {
17 |
18 |
19 | // 记录提交次数
20 | public static final Map TASK_PRODUCT_COUNT = new ConcurrentHashMap();
21 | // 记录消费次数
22 | public static final Map TASK_CONSUME_COUNT = new ConcurrentHashMap();
23 | // 记录任务执行失败次数
24 | public static final Map TASK_FAIL_COUNT = new ConcurrentHashMap();
25 |
26 | @Override
27 | public void produce(TU tu) {
28 | AtomicLong count = TASK_PRODUCT_COUNT.get(tu.getQueueName());
29 | if (count == null) {
30 | AtomicLong atomicLong = new AtomicLong(1);
31 | TASK_PRODUCT_COUNT.put(tu.getQueueName(), atomicLong);
32 | } else {
33 | count.incrementAndGet();
34 | }
35 | }
36 |
37 | @Override
38 | public void consume(TU tu) {
39 | AtomicLong count = TASK_CONSUME_COUNT.get(tu.getQueueName());
40 | if (count == null) {
41 | AtomicLong atomicLong = new AtomicLong(1);
42 | TASK_CONSUME_COUNT.put(tu.getQueueName(), atomicLong);
43 | } else {
44 | count.incrementAndGet();
45 | }
46 | }
47 |
48 | @Override
49 | public void exceptionIncr(String name) {
50 | AtomicLong count = TASK_FAIL_COUNT.get(name);
51 | if (count == null) {
52 | AtomicLong atomicLong = new AtomicLong(1);
53 | TASK_FAIL_COUNT.put(name, atomicLong);
54 | } else {
55 | count.incrementAndGet();
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * context是Task系统各个module都需要依赖的模块,在这里定义了Task运行期的上下文信息和各个module需要实现的功能接口
3 | *
4 | * @author WangJun
5 | * @version 1.0 16/5/28
6 | */
7 | package com.peaceful.task.kernal;
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/queue/local/LocalQueue.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.queue.local;
2 |
3 |
4 | import com.peaceful.task.kernal.TaskQueue;
5 |
6 | import java.util.HashMap;
7 | import java.util.Map;
8 | import java.util.Queue;
9 | import java.util.concurrent.ArrayBlockingQueue;
10 |
11 | /**
12 | * 仅用于本地测试
13 | *
14 | * Created by wangjun on 16/1/13.
15 | * @since 1.7
16 | */
17 | public class LocalQueue implements TaskQueue {
18 |
19 | Map> map = new HashMap>();
20 |
21 | @Override
22 | public long size(String name) {
23 | if (map.containsKey(name)) {
24 | return map.get(name).size();
25 | }
26 | return 0;
27 | }
28 |
29 | @Override
30 | public synchronized boolean push(String name, String object) {
31 | if (map.containsKey(name)) {
32 | return map.get(name).offer(object);
33 | } else {
34 | Queue queue = new ArrayBlockingQueue(1024);
35 | map.put(name, queue);
36 | return map.get(name).offer(object);
37 | }
38 | }
39 |
40 | @Override
41 | public String pop(String name) {
42 | if (map.containsKey(name)) {
43 | return map.get(name).poll();
44 | }
45 | return null;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/task-kernal/src/main/java/com/peaceful/task/kernal/queue/redis/RedisQueue.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal.queue.redis;
2 |
3 | import com.peaceful.common.redis.service.Redis;
4 | import com.peaceful.task.kernal.TaskQueue;
5 |
6 | /**
7 | * @author WangJun
8 | * @version 1.0 16/1/10
9 | */
10 | public class RedisQueue implements TaskQueue {
11 |
12 | @Override
13 | public boolean push(String key, String object) {
14 | Redis.cmd().lpush(key, object);
15 | return true;
16 | }
17 |
18 | @Override
19 | public String pop(String key) {
20 | return Redis.cmd().rpop(key);
21 | }
22 |
23 | @Override
24 | public long size(String key) {
25 | return Redis.cmd().llen(key);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/task-kernal/src/main/resources/application.conf:
--------------------------------------------------------------------------------
1 | akka {
2 | loggers = ["akka.event.slf4j.Slf4jLogger"]
3 | // loglevel = "DEBUG"
4 | loglevel = "INFO"
5 | logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
6 | actor {
7 | debug {
8 | # enable DEBUG logging of all AutoReceiveMessages (Kill, PoisonPill et.c.)
9 | autoreceive = on
10 | # enable DEBUG logging of actor lifecycle changes
11 | lifecycle = on
12 | # enable DEBUG logging of unhandled messages
13 | unhandled = on
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/task-kernal/src/main/resources/task-reference.conf:
--------------------------------------------------------------------------------
1 | # task系统配置文件
2 |
3 | task {
4 |
5 | # 系统命名,主要用于创建多个系统实例时的命名空间的区分
6 | name = "TASK"
7 |
8 | # 启动模式,如果是client模式,只可以提交任务,不会调度任务执行,server模式可提交任务,也可以调度任务执行
9 | boot-mode = "server" # server[client]
10 |
11 | # 开发模式,在test模式下,系统会打印更多的日志信息
12 | develop-mode = "test" # test[product]
13 |
14 | # 任务队列实现,你也可以实现自己的队列通过继承TaskQueue
15 | queue = "com.peaceful.task.kernal.queue.redis.RedisQueue"
16 |
17 | # 任务bean实例获取工厂,任务在被执行时,需要获取任务的实例,你也可以实现自己的bean管理工厂,比如对接Spring的BeanFactory或其它DI容器
18 | bean-factory = "com.peaceful.task.kernal.dispatch.TaskBeanFactoryImpl"
19 |
20 | // 任务执行器
21 | executor = [
22 |
23 | {
24 | name: "default"
25 | # 最简单的executor实现
26 | implementation: "com.peaceful.task.kernal.dispatch.executor.SimpleTaskExecutor"
27 | },
28 | {
29 | name: "jucExecutor"
30 | implementation: "com.peaceful.task.kernal.dispatch.executor.JUCTaskExecutor"
31 | }
32 | ]
33 |
34 | # 从MQ中拉取任务的频率
35 | dispatch-tick = 2s
36 | }
--------------------------------------------------------------------------------
/task-kernal/src/test/java/com/peaceful/task/kernal/Hello.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | import com.peaceful.task.kernal.annotation.Task;
4 |
5 | import java.util.List;
6 | import java.util.Map;
7 | import java.util.Set;
8 |
9 | /**
10 | * @author WangJun
11 | * @version 1.0 16/1/11
12 | */
13 | public class Hello {
14 |
15 | @Task(value = "Test06",executor = "jucExecutor")
16 | public void say(String msg) throws InterruptedException {
17 | // Thread.sleep(1000);
18 | int x= 1 /0;
19 | System.out.println(msg);
20 | }
21 |
22 | @Task("Test08")
23 | public void testPOJO(User user) throws InterruptedException {
24 | System.out.println(user.name);
25 | }
26 |
27 | public void testMap(Map user) throws InterruptedException {
28 | System.out.println(user.get("01").name);
29 | }
30 |
31 | public void testList(List user) throws InterruptedException {
32 | System.out.println(user.get(0).name);
33 | }
34 |
35 | public void testSet(Set user) throws InterruptedException {
36 | System.out.println(user);
37 | }
38 |
39 | public void testAll(String msg, User user, Map userMap, List userList, Set userSet) throws InterruptedException {
40 | System.out.println(msg);
41 | System.out.println(userMap.get("01").name);
42 | System.out.println(userList.get(0).name);
43 | System.out.println(user);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/task-kernal/src/test/java/com/peaceful/task/kernal/SetUp.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | import java.util.*;
4 |
5 | /**
6 | * @author WangJun
7 | * @version 1.0 16/3/30
8 | */
9 | public class SetUp {
10 |
11 | public static void main(String[] args) throws InterruptedException {
12 |
13 | Task task = Task.create();
14 | Hello hello = task.registerASyncClass(Hello.class);
15 | int time = 1000;
16 | for (int i=0;i< time;i++) {
17 | // 基本类型测试
18 | hello.say("hello world!");
19 |
20 | User user = new User();
21 | user.name = "123";
22 |
23 | // 简单POJO类型
24 | hello.testPOJO(user);
25 |
26 | // Map类型
27 | Map userMap = new HashMap();
28 | userMap.put("01", user);
29 | hello.testMap(userMap);
30 |
31 | // List 类型
32 | List users = new ArrayList();
33 | users.add(user);
34 | hello.testList(users);
35 |
36 | // Set 类型
37 | Set userSet = new HashSet();
38 | userSet.add(user);
39 | hello.testSet(userSet);
40 |
41 | hello.testAll("Hello World!", user, userMap, users, userSet);
42 | }
43 |
44 | // int time = 1;
45 | /* int time = 10000;
46 | for (int i = 0; i < time; i++) {
47 | hello.say("hello world");
48 | }*/
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/task-kernal/src/test/java/com/peaceful/task/kernal/User.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.kernal;
2 |
3 | /**
4 | * @author WangJun
5 | * @version 1.0 16/4/14
6 | */
7 | public class User {
8 |
9 | public String name;
10 | public int id;
11 | }
12 |
--------------------------------------------------------------------------------
/task-kernal/src/test/resources/log4j.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/task-ops/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/.DS_Store
--------------------------------------------------------------------------------
/task-ops/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | com.peaceful
9 | peaceful-parent
10 | 1.0-SNAPSHOT
11 |
12 |
13 | com.peaceful
14 | task-ops
15 | 2.6-SNAPSHOT
16 |
17 |
18 |
19 |
20 | org.springframework
21 | spring-webmvc
22 |
23 |
24 |
25 | org.springframework.security
26 | spring-security-web
27 |
28 |
29 |
30 | org.springframework.security
31 | spring-security-config
32 |
33 |
34 |
35 |
36 | org.freemarker
37 | freemarker
38 |
39 |
40 |
41 |
42 |
43 | org.mybatis
44 | mybatis-spring
45 | 1.2.2
46 |
47 |
48 |
49 | org.mybatis
50 | mybatis
51 | 3.2.8
52 |
53 |
54 |
55 |
56 | jstl
57 | jstl
58 |
59 |
60 |
61 | com.peaceful
62 | peaceful-common-utils
63 | 1.0-SNAPSHOT
64 |
65 |
66 |
67 | javax
68 | javaee-api
69 | 7.0
70 | provided
71 |
72 |
73 |
74 | org.apache.httpcomponents
75 | httpclient
76 |
77 |
78 |
79 | com.typesafe
80 | config
81 | 1.2.1
82 |
83 |
84 |
85 | com.peaceful
86 | redis-manage
87 | 1.1-SNAPSHOT
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/task-ops/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/.DS_Store
--------------------------------------------------------------------------------
/task-ops/src/main/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/.DS_Store
--------------------------------------------------------------------------------
/task-ops/src/main/filters/dev.properties:
--------------------------------------------------------------------------------
1 | #dev.properties
2 | #Sun Mar 30 01:01:22 CST 2014
3 | #create by WangJun
4 | #email wangjuntytl@163.com
5 |
6 | #env conf
7 | running.mode=dev
8 |
9 | # log conf
10 | root.log.level=debug
11 | root.log.appender=console-appender
12 |
--------------------------------------------------------------------------------
/task-ops/src/main/filters/product.properties:
--------------------------------------------------------------------------------
1 | #product.properties
2 | #Sun Mar 30 01:01:22 CST 2014
3 | #create by WangJun
4 | #email wangjuntytl@163.com
5 |
6 | #env conf
7 | running.mode=product
8 |
9 | # log conf
10 | root.log.level=info
11 | root.log.appender=file-appender
12 |
--------------------------------------------------------------------------------
/task-ops/src/main/filters/test.properties:
--------------------------------------------------------------------------------
1 | #test.properties
2 | #Sun Mar 30 01:01:22 CST 2014
3 | #create by WangJun
4 | #email wangjuntytl@163.com
5 |
6 | #env conf
7 | running.mode=test
8 |
9 | # log conf
10 | root.log.level=debug
11 | root.log.appender=file-appender
--------------------------------------------------------------------------------
/task-ops/src/main/java/com/peaceful/task/ops/admin/controller/ConfController.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.ops.admin.controller;
2 |
3 | import com.peaceful.common.util.Http;
4 | import com.peaceful.task.ops.common.Conf;
5 | import org.springframework.context.annotation.Description;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.ResponseBody;
9 |
10 | /**
11 | * @author WangJun
12 | * @version 1.0 16/4/7
13 | */
14 | @RequestMapping("/conf")
15 | @Controller
16 | @ResponseBody
17 | public class ConfController {
18 |
19 | @RequestMapping("/cluster")
20 | @Description("获取集群列表")
21 | public void getClusterList() {
22 | Http.responseJSON(Conf.getConf().clusterList);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/task-ops/src/main/java/com/peaceful/task/ops/admin/controller/OnloadController.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.ops.admin.controller;
2 |
3 | import org.springframework.stereotype.Controller;
4 |
5 | /**
6 | * @author WangJun
7 | * @version 1.0 16/4/25
8 | */
9 | @Controller
10 | public class OnloadController {
11 |
12 |
13 | static {
14 |
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/task-ops/src/main/java/com/peaceful/task/ops/admin/controller/WelcomeController.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.ops.admin.controller;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 |
8 | import static com.peaceful.common.redis.service.Redis.cmd;
9 |
10 | /**
11 | * @author WangJun
12 | * @version 1.0 16/3/31
13 | */
14 | @RequestMapping("/")
15 | @Controller
16 | public class WelcomeController {
17 |
18 |
19 | @RequestMapping(value = {"index", ""})
20 | public String index(HttpServletRequest request) {
21 | return "welcome/index";
22 | }
23 |
24 | @RequestMapping(value = "01")
25 | public String template01(HttpServletRequest request) {
26 | return "welcome/template01";
27 | }
28 |
29 | @RequestMapping(value = "02")
30 | public String template02(HttpServletRequest request) {
31 | return "welcome/template02";
32 | }
33 |
34 | @RequestMapping(value = "03")
35 | public String template03(HttpServletRequest request) {
36 | return "welcome/template03";
37 | }
38 |
39 | @RequestMapping(value = "04")
40 | public String template04(HttpServletRequest request) {
41 | return "welcome/template04";
42 | }
43 |
44 |
45 | @RequestMapping(value = {"help"})
46 | public String help(HttpServletRequest request) {
47 | return "help/index";
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/task-ops/src/main/java/com/peaceful/task/ops/common/ClusterConsoleFilter.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.ops.common;
2 |
3 | import javax.servlet.*;
4 | import javax.servlet.http.HttpServletRequest;
5 | import java.io.IOException;
6 | import java.util.List;
7 |
8 | /**
9 | * @author WangJun
10 | * @version 1.0 15/9/25
11 | * @since 1.6
12 | */
13 |
14 | public class ClusterConsoleFilter implements Filter {
15 |
16 |
17 | @Override
18 | public void init(FilterConfig filterConfig) throws ServletException {
19 |
20 | }
21 |
22 | @Override
23 | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
24 | HttpServletRequest request = (HttpServletRequest) servletRequest;
25 | String currentCluster = request.getParameter("currentCluster");
26 | if (currentCluster == null || currentCluster.equals("")) {
27 | List keys = Conf.getConf().clusterList;
28 | for (String key : keys) {
29 | currentCluster = key;
30 | break;
31 | }
32 | }
33 | request.setAttribute("currentCluster", currentCluster);
34 | filterChain.doFilter(request, servletResponse);
35 | }
36 |
37 | @Override
38 | public void destroy() {
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/task-ops/src/main/java/com/peaceful/task/ops/common/Conf.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.ops.common;
2 |
3 | import com.typesafe.config.Config;
4 | import com.typesafe.config.ConfigFactory;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.concurrent.Executors;
11 | import java.util.concurrent.ScheduledExecutorService;
12 | import java.util.concurrent.TimeUnit;
13 |
14 | /**
15 | * container cluster list conf and web front-end conf
16 | *
17 | * @author WangJun
18 | * @version 1.0 15/9/24
19 | * @since 1.6
20 | */
21 |
22 | public class Conf {
23 |
24 | public List clusterList = new ArrayList();
25 | private Logger logger = LoggerFactory.getLogger(getClass());
26 | private static final ScheduledExecutorService SCHEDULE = Executors.newScheduledThreadPool(1);
27 |
28 | private Conf() {
29 | SCHEDULE.scheduleAtFixedRate(new Runnable() {
30 | @Override
31 | public void run() {
32 | Config config = ConfigFactory.load("taskCluster");
33 | // cluster list
34 | List list = config.getStringList("taskCluster.clusterList");
35 | clusterList = list;
36 | }
37 | },0,5, TimeUnit.SECONDS);
38 |
39 |
40 | }
41 |
42 | private static class Single {
43 | public static Conf conf = new Conf();
44 | }
45 |
46 | public static Conf getConf() {
47 | return Single.conf;
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/task-ops/src/main/java/com/peaceful/task/ops/common/SQLiteHelper.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.ops.common;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.apache.commons.lang3.exception.ExceptionUtils;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.sql.*;
9 |
10 | /**
11 | * @author WangJun
12 | * @version 1.0 16/4/25
13 | */
14 | public class SQLiteHelper {
15 |
16 | private static final String userDir = System.getProperty("user.dir");
17 | private static final String driver = "org.sqlite.JDBC";
18 | private static final String url = "jdbc:sqlite:"+userDir+"/task.dashboard.db";
19 | private static Connection connection = null;
20 | private static final Object CONN_MONITOR = new Object();
21 | private static final Logger LOGGER = LoggerFactory.getLogger(SQLiteHelper.class);
22 |
23 | public static Connection getConn() {
24 |
25 | if (connection != null) {
26 | return connection;
27 | } else {
28 | synchronized (CONN_MONITOR) {
29 | if (connection != null) {
30 | return connection;
31 | }
32 | try {
33 | Class.forName(driver);
34 | // 默认在当前目录下创建
35 | connection = DriverManager.getConnection(url);
36 | return connection;
37 | } catch (Exception e) {
38 | System.err.println(e.getClass().getName() + ": " + e.getMessage());
39 | LOGGER.error(ExceptionUtils.getRootCauseMessage(e));
40 | return null;
41 | }
42 | }
43 | }
44 | }
45 |
46 | public static int createTable(String sql, String... indexs) throws SQLException {
47 | String table = sql.split("\\s+")[2];
48 | if (StringUtils.isBlank(table)) {
49 | return -1;
50 | }
51 | String existSql = String.format("select count(*) from sqlite_master where type='table' and name = '%s' ", table);
52 | PreparedStatement preparedStatement = getConn().prepareStatement(existSql);
53 | ResultSet resultSet = preparedStatement.executeQuery();
54 | if (resultSet.getInt(1) > 0) {
55 | resultSet.close();
56 | preparedStatement.close();
57 | return 0;
58 | } else {
59 | resultSet.close();
60 | preparedStatement.close();
61 | execute(sql);
62 | if (indexs != null && indexs.length > 0) {
63 | for (String index : indexs) {
64 | sql = String.format("CREATE INDEX %s_%s_index ON %s (%s)", table, index, table, index);
65 | execute(sql);
66 | }
67 | }
68 | return 1;
69 | }
70 | }
71 |
72 | /**
73 | * execute sql
74 | *
75 | * @param sql
76 | * @throws SQLException
77 | */
78 | public static void execute(String sql) throws SQLException {
79 | PreparedStatement preparedStatement = getConn().prepareStatement(sql);
80 | LOGGER.info("executor sql {} ,result is {} ", sql, preparedStatement.execute());
81 | preparedStatement.close();
82 | }
83 |
84 | public static int executeUpdate(String sql) throws SQLException {
85 | PreparedStatement preparedStatement = getConn().prepareStatement(sql);
86 | int rows = preparedStatement.executeUpdate();
87 | LOGGER.info("executor sql {} ,result is {} ", sql, rows);
88 | preparedStatement.close();
89 | return rows;
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/task-ops/src/main/java/com/peaceful/task/ops/task/api/CycleQueue.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.ops.task.api;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 基于数据实现的循环队列,用于存取最新的固定长度的数据
7 | *
8 | * @author WangJun
9 | * @version 1.0 15/9/16
10 | * @since 1.6
11 | */
12 |
13 | public class CycleQueue implements Serializable {
14 |
15 | /**
16 | * 数组下一个索引位置
17 | */
18 | private int index;
19 | /**
20 | * 循环队列的大小
21 | */
22 | private int length;
23 | /**
24 | * 是否队列已处于循环转态
25 | */
26 | private boolean cycle;
27 | /**
28 | * 存取具体数据的容器
29 | */
30 | private Object[] data;
31 |
32 |
33 | /**
34 | * 利用指定大小的值初始化循环队列容器
35 | *
36 | * @param length
37 | */
38 | public CycleQueue(int length) {
39 | this.length = length;
40 | data = new Object[length];
41 | }
42 |
43 | /**
44 | * 线程安全的存入最新值到容器中
45 | *
46 | * @param value
47 | */
48 | public synchronized void push(E value) {
49 | if (index >= length) {
50 | index = index - length;
51 | cycle = true;
52 | }
53 | data[index] = value;
54 | index++;
55 | }
56 |
57 | /**
58 | * 获取目前容器内的所有值
59 | *
60 | * @return
61 | */
62 | public Object[] get() {
63 | Object[] truthData = new Object[length];
64 | int currentIndex = (index - 1);
65 | if (cycle) {
66 | for (int i = (length - 1); i >= 0; i--) {
67 | if (currentIndex < 0) {
68 | truthData[i] = data[currentIndex + length];
69 | } else {
70 | truthData[i] = data[currentIndex];
71 | }
72 | currentIndex--;
73 | }
74 | } else {
75 | Object[] data = new Object[index];
76 | for (int i = 0; i <= currentIndex; i++) {
77 | data[i] = this.data[i];
78 | }
79 | return data;
80 | }
81 | return truthData;
82 | }
83 |
84 | /**
85 | * 获取容器内的最新值
86 | *
87 | * @return
88 | */
89 | public E getCurrentValue() {
90 | int currentIndex = (index - 1);
91 | if (currentIndex < 0) currentIndex = 0;
92 | return (E) data[currentIndex];
93 | }
94 |
95 | @Override
96 | public String toString() {
97 | Object[] data = get();
98 | String res = "[ ";
99 | for (Object object : data) {
100 | res += object + ",";
101 | }
102 | res = res.substring(0, res.length() - 1);
103 | res += " ]";
104 | return res;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/task-ops/src/main/java/com/peaceful/task/ops/task/api/GraphData.java:
--------------------------------------------------------------------------------
1 | package com.peaceful.task.ops.task.api;
2 |
3 | /**
4 | * @author WangJun
5 | * @version 1.0 16/4/5
6 | */
7 | public class GraphData {
8 |
9 | public String tag;
10 | public CycleQueue timeAxis;
11 | public CycleQueue produceAxis;
12 | public CycleQueue consumeAxis;
13 |
14 | public GraphData(String tag,int size){
15 | this.tag = tag;
16 | this.timeAxis = new CycleQueue(size);
17 | produceAxis = new CycleQueue(size);
18 | consumeAxis = new CycleQueue(size);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/task-ops/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | #create by WangJun
2 | #date 2014-10-29
3 | #app global configs
4 |
5 | dev.mode=${dev.mode}
6 | running.mode=${dev.mode}
7 | build.version=${timestamp}
8 |
9 |
--------------------------------------------------------------------------------
/task-ops/src/main/resources/log4j.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/task-ops/src/main/resources/taskCluster.conf:
--------------------------------------------------------------------------------
1 | taskCluster: {
2 |
3 | clusterList: ["TASK","demo02","demo03"]
4 |
5 | }
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/.DS_Store
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/page/ftl/test.ftl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/WEB-INF/page/ftl/test.ftl
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/page/jsp/errors/404.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: wangjun
4 | Date: 15/1/27
5 | Time: 上午11:03
6 | To change this weixin.template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 | Task
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/page/jsp/errors/error.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: wangjun
4 | Date: 15/1/27
5 | Time: 上午11:03
6 | To change this weixin.template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 | Task
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ERROR
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/page/jsp/help/index.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: wangjun
4 | Date: 15/1/27
5 | Time: 上午11:03
6 | To change this weixin.template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Url Search
19 |
20 |
21 |
22 |
23 |
24 |
38 |
39 |
48 |
84 |
85 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/page/jsp/test.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: wangjun
4 | Date: 14/11/1
5 | Time: 下午1:21
6 | To change this weixin.template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 |
12 |
13 |
14 | hello world
15 |
16 |
17 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/page/jsp/welcome/template01.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: wangjun
4 | Date: 15/1/27
5 | Time: 上午11:03
6 | To change this weixin.template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 | <%--container 居中,container-fluid 满屏--%>
12 |
13 | Hello world
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/page/jsp/welcome/template02.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: wangjun
4 | Date: 15/1/27
5 | Time: 上午11:03
6 | To change this weixin.template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/page/jsp/welcome/template03.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Created by IntelliJ IDEA.
3 | User: wangjun
4 | Date: 15/1/27
5 | Time: 上午11:03
6 | To change this weixin.template use File | Settings | File Templates.
7 | --%>
8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %>
9 |
10 |
11 | <%--container 居中,container-fluid 满屏--%>
12 |
13 |
14 |
15 |
Simple Sidebar
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/springMvc-servlet.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
55 |
56 |
57 | errors/error
58 | errors/err
59 |
60 |
61 |
62 |
63 | 500
64 | 404
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | index.html
8 |
9 |
10 | contextConfigLocation
11 |
12 | WEB-INF/springMvc-servlet.xml
13 |
14 |
15 |
16 | springMvc
17 | org.springframework.web.servlet.DispatcherServlet
18 | 1
19 |
20 |
21 | springMvc
22 | /
23 |
24 |
25 | org.springframework.web.context.ContextLoaderListener
26 |
27 |
28 | org.springframework.web.context.request.RequestContextListener
29 |
30 |
31 | org.springframework.web.util.IntrospectorCleanupListener
32 |
33 |
34 | springSecurityFilterChain
35 | org.springframework.web.filter.DelegatingFilterProxy
36 |
37 | targetFilterLifecycle
38 | true
39 |
40 |
41 |
42 | springSecurityFilterChain
43 | /*
44 |
45 |
46 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/css/metisMenu.min.css:
--------------------------------------------------------------------------------
1 | /*
2 | * metismenu - v2.5.0
3 | * A jQuery menu plugin
4 | * https://github.com/onokumus/metisMenu#readme
5 | *
6 | * Made by Osman Nuri Okumuş (https://github.com/onokumus)
7 | * Under MIT License
8 | */
9 |
10 | .metismenu .arrow {
11 | float: right;
12 | line-height: 1.42857
13 | }
14 |
15 | [dir=rtl] .metismenu .arrow {
16 | float: left
17 | }
18 |
19 | .metismenu .glyphicon.arrow:before {
20 | content: "\e079"
21 | }
22 |
23 | .metismenu .active > a > .glyphicon.arrow:before {
24 | content: "\e114"
25 | }
26 |
27 | .metismenu .fa.arrow:before {
28 | content: "\f104"
29 | }
30 |
31 | .metismenu .active > a > .fa.arrow:before {
32 | content: "\f107"
33 | }
34 |
35 | .metismenu .ion.arrow:before {
36 | content: "\f3d2"
37 | }
38 |
39 | .metismenu .active > a > .ion.arrow:before {
40 | content: "\f3d0"
41 | }
42 |
43 | .metismenu .plus-times {
44 | float: right
45 | }
46 |
47 | [dir=rtl] .metismenu .plus-times {
48 | float: left
49 | }
50 |
51 | .metismenu .fa.plus-times:before {
52 | content: "\f067"
53 | }
54 |
55 | .metismenu .active > a > .fa.plus-times {
56 | -webkit-transform: rotate(45deg);
57 | -ms-transform: rotate(45deg);
58 | -o-transform: rotate(45deg);
59 | transform: rotate(45deg)
60 | }
61 |
62 | .metismenu .plus-minus {
63 | float: right
64 | }
65 |
66 | [dir=rtl] .metismenu .plus-minus {
67 | float: left
68 | }
69 |
70 | .metismenu .fa.plus-minus:before {
71 | content: "\f067"
72 | }
73 |
74 | .metismenu .active > a > .fa.plus-minus:before {
75 | content: "\f068"
76 | }
77 |
78 | .metismenu .collapse {
79 | display: none
80 | }
81 |
82 | .metismenu .collapse.in {
83 | display: block
84 | }
85 |
86 | .metismenu .collapsing {
87 | position: relative;
88 | height: 0;
89 | overflow: hidden;
90 | -webkit-transition-timing-function: ease;
91 | -o-transition-timing-function: ease;
92 | transition-timing-function: ease;
93 | -webkit-transition-duration: .35s;
94 | -o-transition-duration: .35s;
95 | transition-duration: .35s;
96 | -webkit-transition-property: height, visibility;
97 | -o-transition-property: height, visibility;
98 | transition-property: height, visibility
99 | }
100 |
101 |
102 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/ionicons.eot
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/fonts/ionicons.woff
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/image/123.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/image/123.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/image/header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/image/header.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/js/helper/Map.js:
--------------------------------------------------------------------------------
1 | Array.prototype.remove = function(s) {
2 | for (var i = 0; i < this.length; i++) {
3 | if (s == this[i])
4 | this.splice(i, 1);
5 | }
6 | };
7 |
8 | /**
9 | * Simple Map
10 | *
11 | *
12 | * var m = new Map();
13 | * m.put('key','value');
14 | * ...
15 | * var s = "";
16 | * m.each(function(key,value,index){
17 | * s += index+":"+ key+"="+value+"/n";
18 | * });
19 | * alert(s);
20 | *
21 | * @author dewitt
22 | * @date 2008-05-24
23 | */
24 | function Map() {
25 | /** 存放键的数组(遍历用到) */
26 | this.keys = [];
27 | /** 存放数据 */
28 | this.data = {};
29 |
30 | /**
31 | * 放入一个键值对
32 | * @param {String} key
33 | * @param {Object} value
34 | */
35 | this.put = function(key, value) {
36 | if(this.data[key] == null){
37 | this.keys.push(key);
38 | }
39 | this.data[key] = value;
40 | };
41 |
42 | /**
43 | * 获取某键对应的值
44 | * @param {String} key
45 | * @return {Object} value
46 | */
47 | this.get = function(key) {
48 | return this.data[key];
49 | };
50 |
51 | /**
52 | * 删除一个键值对
53 | * @param {String} key
54 | */
55 | this.remove = function(key) {
56 | this.keys.remove(key);
57 | this.data[key] = null;
58 | };
59 |
60 | /**
61 | * 遍历Map,执行处理函数
62 | *
63 | * @param {Function} 回调函数 function(key,value,index){..}
64 | */
65 | this.each = function(fn){
66 | if(typeof fn != 'function'){
67 | return;
68 | }
69 | var len = this.keys.length;
70 | for(var i=0;i").append($("").attr("class", "active").append($('')).html( clusterList[i])));
8 | } else {
9 | $("#cluster_list").append($("").append($("").append($('')).html( clusterList[i])));
10 | }
11 |
12 | }
13 | /*var url = window.location;
14 | var element = $('ul.nav a').filter(function() {
15 | return this.href == url;
16 | }).addClass('active').parent().parent().addClass('in').parent();
17 | if (element.is('li')) {
18 | element.addClass('active');
19 | }*/
20 | });
21 |
22 | $(document).on('click', '.cluster_nav', function () {
23 | var name = $(this).html();
24 | var url = window.location.pathname;
25 | window.location.href = url + "?currentCluster=" + name;
26 | });
27 | });
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/.DS_Store
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/image/TaskDispatch-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/image/TaskDispatch-01.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/image/TaskDispatch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/image/TaskDispatch.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/image/TaskModal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/image/TaskModal.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/image/TaskMonitor-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/image/TaskMonitor-01.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/image/TaskMonitor-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/image/TaskMonitor-02.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/image/TaskMonitor-03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/image/TaskMonitor-03.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/image/TaskMonitor-04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/image/TaskMonitor-04.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/image/TaskProcess.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/image/TaskProcess.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template01/dashboard.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Base structure
3 | */
4 |
5 | /* Move down content because we have a fixed navbar that is 50px tall */
6 | body {
7 | padding-top: 50px;
8 | }
9 |
10 |
11 | /*
12 | * Global add-ons
13 | */
14 |
15 | .sub-header {
16 | padding-bottom: 10px;
17 | border-bottom: 1px solid #eee;
18 | }
19 |
20 | /*
21 | * Top navigation
22 | * Hide default border to remove 1px line.
23 | */
24 | .navbar-fixed-top {
25 | border: 0;
26 | }
27 |
28 | /*
29 | * Sidebar
30 | */
31 |
32 | /* Hide for mobile, show later */
33 | .sidebar {
34 | display: none;
35 | }
36 | @media (min-width: 768px) {
37 | .sidebar {
38 | position: fixed;
39 | top: 51px;
40 | bottom: 0;
41 | left: 0;
42 | z-index: 1000;
43 | display: block;
44 | padding: 20px;
45 | overflow-x: hidden;
46 | overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
47 | background-color: #f5f5f5;
48 | border-right: 1px solid #eee;
49 | }
50 | }
51 |
52 | /* Sidebar navigation */
53 | .nav-sidebar {
54 | margin-right: -21px; /* 20px padding + 1px border */
55 | margin-bottom: 20px;
56 | margin-left: -20px;
57 | }
58 | .nav-sidebar > li > a {
59 | padding-right: 20px;
60 | padding-left: 20px;
61 | }
62 | .nav-sidebar > .active > a,
63 | .nav-sidebar > .active > a:hover,
64 | .nav-sidebar > .active > a:focus {
65 | color: #fff;
66 | background-color: #428bca;
67 | }
68 |
69 |
70 | /*
71 | * Main content
72 | */
73 |
74 | .main {
75 | padding: 20px;
76 | }
77 | @media (min-width: 768px) {
78 | .main {
79 | padding-right: 40px;
80 | padding-left: 40px;
81 | }
82 | }
83 | .main .page-header {
84 | margin-top: 0;
85 | }
86 |
87 |
88 | /*
89 | * Placeholder dashboard ideas
90 | */
91 |
92 | .placeholders {
93 | margin-bottom: 30px;
94 | text-align: center;
95 | }
96 | .placeholders h4 {
97 | margin-bottom: 0;
98 | }
99 | .placeholder {
100 | margin-bottom: 20px;
101 | }
102 | .placeholder img {
103 | display: inline-block;
104 | border-radius: 50%;
105 | }
106 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template02/sb-admin-2.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | $('#side-menu').metisMenu();
3 |
4 | });
5 |
6 | //Loads the correct sidebar on window load,
7 | //collapses the sidebar on window resize.
8 | // Sets the min-height of #page-wrapper to window size
9 | $(function() {
10 | $(window).on("load resize", function() {
11 | var topOffset = 50;
12 | var width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
13 | if (width < 768) {
14 | $('div.navbar-collapse').addClass('collapse');
15 | topOffset = 100; // 2-row-menu
16 | } else {
17 | $('div.navbar-collapse').removeClass('collapse');
18 | }
19 |
20 | var height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1;
21 | height = height - topOffset;
22 | if (height < 1) height = 1;
23 | if (height > topOffset) {
24 | $("#page-wrapper").css("min-height", (height) + "px");
25 | }
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template03/simple-sidebar.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Start Bootstrap - Simple Sidebar HTML Template (http://startbootstrap.com)
3 | * Code licensed under the Apache License v2.0.
4 | * For details, see http://www.apache.org/licenses/LICENSE-2.0.
5 | */
6 |
7 | /* Toggle Styles */
8 |
9 | #wrapper {
10 | padding-left: 0;
11 | -webkit-transition: all 0.5s ease;
12 | -moz-transition: all 0.5s ease;
13 | -o-transition: all 0.5s ease;
14 | transition: all 0.5s ease;
15 | }
16 |
17 | #wrapper.toggled {
18 | padding-left: 250px;
19 | }
20 |
21 | #sidebar-wrapper {
22 | z-index: 1000;
23 | position: fixed;
24 | left: 250px;
25 | width: 0;
26 | height: 100%;
27 | margin-left: -250px;
28 | overflow-y: auto;
29 | background: #000;
30 | -webkit-transition: all 0.5s ease;
31 | -moz-transition: all 0.5s ease;
32 | -o-transition: all 0.5s ease;
33 | transition: all 0.5s ease;
34 | }
35 |
36 | #wrapper.toggled #sidebar-wrapper {
37 | width: 250px;
38 | }
39 |
40 | #page-content-wrapper {
41 | width: 100%;
42 | position: absolute;
43 | padding: 15px;
44 | }
45 |
46 | #wrapper.toggled #page-content-wrapper {
47 | position: absolute;
48 | margin-right: -250px;
49 | }
50 |
51 | /* Sidebar Styles */
52 |
53 | .sidebar-nav {
54 | position: absolute;
55 | top: 0;
56 | width: 250px;
57 | margin: 0;
58 | padding: 0;
59 | list-style: none;
60 | }
61 |
62 | .sidebar-nav li {
63 | text-indent: 20px;
64 | line-height: 40px;
65 | }
66 |
67 | .sidebar-nav li a {
68 | display: block;
69 | text-decoration: none;
70 | color: #999999;
71 | }
72 |
73 | .sidebar-nav li a:hover {
74 | text-decoration: none;
75 | color: #fff;
76 | background: rgba(255,255,255,0.2);
77 | }
78 |
79 | .sidebar-nav li a:active,
80 | .sidebar-nav li a:focus {
81 | text-decoration: none;
82 | }
83 |
84 | .sidebar-nav > .sidebar-brand {
85 | height: 65px;
86 | font-size: 18px;
87 | line-height: 60px;
88 | }
89 |
90 | .sidebar-nav > .sidebar-brand a {
91 | color: #999999;
92 | }
93 |
94 | .sidebar-nav > .sidebar-brand a:hover {
95 | color: #fff;
96 | background: none;
97 | }
98 |
99 | @media(min-width:768px) {
100 | #wrapper {
101 | padding-left: 250px;
102 | }
103 |
104 | #wrapper.toggled {
105 | padding-left: 0;
106 | }
107 |
108 | #sidebar-wrapper {
109 | width: 250px;
110 | }
111 |
112 | #wrapper.toggled #sidebar-wrapper {
113 | width: 0;
114 | }
115 |
116 | #page-content-wrapper {
117 | padding: 20px;
118 | position: relative;
119 | }
120 |
121 | #wrapper.toggled #page-content-wrapper {
122 | position: relative;
123 | margin-right: 0;
124 | }
125 | }
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/avatar.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/avatar04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/avatar04.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/avatar2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/avatar2.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/avatar3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/avatar3.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/avatar5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/avatar5.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/boxed-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/boxed-bg.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/boxed-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/boxed-bg.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/credit/american-express.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/credit/american-express.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/credit/cirrus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/credit/cirrus.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/credit/mastercard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/credit/mastercard.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/credit/mestro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/credit/mestro.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/credit/paypal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/credit/paypal.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/credit/paypal2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/credit/paypal2.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/credit/visa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/credit/visa.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/default-50x50.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/default-50x50.gif
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/icons.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/photo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/photo1.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/photo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/photo2.png
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/photo3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/photo3.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/photo4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/photo4.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/user1-128x128.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/user1-128x128.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/user2-160x160.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/user2-160x160.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/user3-128x128.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/user3-128x128.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/user4-128x128.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/user4-128x128.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/user5-128x128.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/user5-128x128.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/user6-128x128.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/user6-128x128.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/user7-128x128.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/user7-128x128.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/img/user8-128x128.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WangJunTYTL/Task/e9b84759c048c785a46fea49d43d8f9219a4e3f5/task-ops/src/main/webapp/static/template04/img/user8-128x128.jpg
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/skins/skin-black.min.css:
--------------------------------------------------------------------------------
1 | .skin-black .main-header{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.skin-black .main-header .navbar-toggle{color:#333}.skin-black .main-header .navbar-brand{color:#333;border-right:1px solid #eee}.skin-black .main-header>.navbar{background-color:#fff}.skin-black .main-header>.navbar .nav>li>a{color:#333}.skin-black .main-header>.navbar .nav>li>a:hover,.skin-black .main-header>.navbar .nav>li>a:active,.skin-black .main-header>.navbar .nav>li>a:focus,.skin-black .main-header>.navbar .nav .open>a,.skin-black .main-header>.navbar .nav .open>a:hover,.skin-black .main-header>.navbar .nav .open>a:focus,.skin-black .main-header>.navbar .nav>.active>a{background:#fff;color:#999}.skin-black .main-header>.navbar .sidebar-toggle{color:#333}.skin-black .main-header>.navbar .sidebar-toggle:hover{color:#999;background:#fff}.skin-black .main-header>.navbar>.sidebar-toggle{color:#333;border-right:1px solid #eee}.skin-black .main-header>.navbar .navbar-nav>li>a{border-right:1px solid #eee}.skin-black .main-header>.navbar .navbar-custom-menu .navbar-nav>li>a,.skin-black .main-header>.navbar .navbar-right>li>a{border-left:1px solid #eee;border-right-width:0}.skin-black .main-header>.logo{background-color:#fff;color:#333;border-bottom:0 solid transparent;border-right:1px solid #eee}.skin-black .main-header>.logo:hover{background-color:#fcfcfc}@media (max-width:767px){.skin-black .main-header>.logo{background-color:#222;color:#fff;border-bottom:0 solid transparent;border-right:none}.skin-black .main-header>.logo:hover{background-color:#1f1f1f}}.skin-black .main-header li.user-header{background-color:#222}.skin-black .content-header{background:transparent;box-shadow:none}.skin-black .wrapper,.skin-black .main-sidebar,.skin-black .left-side{background-color:#222d32}.skin-black .user-panel>.info,.skin-black .user-panel>.info>a{color:#fff}.skin-black .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-black .sidebar-menu>li>a{border-left:3px solid transparent}.skin-black .sidebar-menu>li:hover>a,.skin-black .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#fff}.skin-black .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-black .sidebar a{color:#b8c7ce}.skin-black .sidebar a:hover{text-decoration:none}.skin-black .treeview-menu>li>a{color:#8aa4af}.skin-black .treeview-menu>li.active>a,.skin-black .treeview-menu>li>a:hover{color:#fff}.skin-black .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-black .sidebar-form input[type="text"],.skin-black .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-black .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-black .sidebar-form input[type="text"]:focus,.skin-black .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-black .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-black .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-black .pace .pace-progress{background:#222}.skin-black .pace .pace-activity{border-top-color:#222;border-left-color:#222}
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/skins/skin-blue.min.css:
--------------------------------------------------------------------------------
1 | .skin-blue .main-header .navbar{background-color:#3c8dbc}.skin-blue .main-header .navbar .nav>li>a{color:#fff}.skin-blue .main-header .navbar .nav>li>a:hover,.skin-blue .main-header .navbar .nav>li>a:active,.skin-blue .main-header .navbar .nav>li>a:focus,.skin-blue .main-header .navbar .nav .open>a,.skin-blue .main-header .navbar .nav .open>a:hover,.skin-blue .main-header .navbar .nav .open>a:focus,.skin-blue .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue .main-header .logo{background-color:#367fa9;color:#fff;border-bottom:0 solid transparent}.skin-blue .main-header .logo:hover{background-color:#357ca5}.skin-blue .main-header li.user-header{background-color:#3c8dbc}.skin-blue .content-header{background:transparent}.skin-blue .wrapper,.skin-blue .main-sidebar,.skin-blue .left-side{background-color:#222d32}.skin-blue .user-panel>.info,.skin-blue .user-panel>.info>a{color:#fff}.skin-blue .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-blue .sidebar-menu>li>a{border-left:3px solid transparent}.skin-blue .sidebar-menu>li:hover>a,.skin-blue .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#3c8dbc}.skin-blue .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-blue .sidebar a{color:#b8c7ce}.skin-blue .sidebar a:hover{text-decoration:none}.skin-blue .treeview-menu>li>a{color:#8aa4af}.skin-blue .treeview-menu>li.active>a,.skin-blue .treeview-menu>li>a:hover{color:#fff}.skin-blue .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-blue .sidebar-form input[type="text"],.skin-blue .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-blue .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue .sidebar-form input[type="text"]:focus,.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8}
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/skins/skin-green.min.css:
--------------------------------------------------------------------------------
1 | .skin-green .main-header .navbar{background-color:#00a65a}.skin-green .main-header .navbar .nav>li>a{color:#fff}.skin-green .main-header .navbar .nav>li>a:hover,.skin-green .main-header .navbar .nav>li>a:active,.skin-green .main-header .navbar .nav>li>a:focus,.skin-green .main-header .navbar .nav .open>a,.skin-green .main-header .navbar .nav .open>a:hover,.skin-green .main-header .navbar .nav .open>a:focus,.skin-green .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-green .main-header .navbar .sidebar-toggle{color:#fff}.skin-green .main-header .navbar .sidebar-toggle:hover{background-color:#008d4c}@media (max-width:767px){.skin-green .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-green .main-header .navbar .dropdown-menu li a{color:#fff}.skin-green .main-header .navbar .dropdown-menu li a:hover{background:#008d4c}}.skin-green .main-header .logo{background-color:#008d4c;color:#fff;border-bottom:0 solid transparent}.skin-green .main-header .logo:hover{background-color:#008749}.skin-green .main-header li.user-header{background-color:#00a65a}.skin-green .content-header{background:transparent}.skin-green .wrapper,.skin-green .main-sidebar,.skin-green .left-side{background-color:#222d32}.skin-green .user-panel>.info,.skin-green .user-panel>.info>a{color:#fff}.skin-green .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-green .sidebar-menu>li>a{border-left:3px solid transparent}.skin-green .sidebar-menu>li:hover>a,.skin-green .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#00a65a}.skin-green .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-green .sidebar a{color:#b8c7ce}.skin-green .sidebar a:hover{text-decoration:none}.skin-green .treeview-menu>li>a{color:#8aa4af}.skin-green .treeview-menu>li.active>a,.skin-green .treeview-menu>li>a:hover{color:#fff}.skin-green .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-green .sidebar-form input[type="text"],.skin-green .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-green .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-green .sidebar-form input[type="text"]:focus,.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-green .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-green .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/skins/skin-purple.min.css:
--------------------------------------------------------------------------------
1 | .skin-purple .main-header .navbar{background-color:#605ca8}.skin-purple .main-header .navbar .nav>li>a{color:#fff}.skin-purple .main-header .navbar .nav>li>a:hover,.skin-purple .main-header .navbar .nav>li>a:active,.skin-purple .main-header .navbar .nav>li>a:focus,.skin-purple .main-header .navbar .nav .open>a,.skin-purple .main-header .navbar .nav .open>a:hover,.skin-purple .main-header .navbar .nav .open>a:focus,.skin-purple .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-purple .main-header .navbar .sidebar-toggle{color:#fff}.skin-purple .main-header .navbar .sidebar-toggle:hover{background-color:#555299}@media (max-width:767px){.skin-purple .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-purple .main-header .navbar .dropdown-menu li a{color:#fff}.skin-purple .main-header .navbar .dropdown-menu li a:hover{background:#555299}}.skin-purple .main-header .logo{background-color:#555299;color:#fff;border-bottom:0 solid transparent}.skin-purple .main-header .logo:hover{background-color:#545096}.skin-purple .main-header li.user-header{background-color:#605ca8}.skin-purple .content-header{background:transparent}.skin-purple .wrapper,.skin-purple .main-sidebar,.skin-purple .left-side{background-color:#222d32}.skin-purple .user-panel>.info,.skin-purple .user-panel>.info>a{color:#fff}.skin-purple .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-purple .sidebar-menu>li>a{border-left:3px solid transparent}.skin-purple .sidebar-menu>li:hover>a,.skin-purple .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#605ca8}.skin-purple .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-purple .sidebar a{color:#b8c7ce}.skin-purple .sidebar a:hover{text-decoration:none}.skin-purple .treeview-menu>li>a{color:#8aa4af}.skin-purple .treeview-menu>li.active>a,.skin-purple .treeview-menu>li>a:hover{color:#fff}.skin-purple .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-purple .sidebar-form input[type="text"],.skin-purple .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-purple .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-purple .sidebar-form input[type="text"]:focus,.skin-purple .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-purple .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-purple .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/skins/skin-red-light.min.css:
--------------------------------------------------------------------------------
1 | .skin-red-light .main-header .navbar{background-color:#dd4b39}.skin-red-light .main-header .navbar .nav>li>a{color:#fff}.skin-red-light .main-header .navbar .nav>li>a:hover,.skin-red-light .main-header .navbar .nav>li>a:active,.skin-red-light .main-header .navbar .nav>li>a:focus,.skin-red-light .main-header .navbar .nav .open>a,.skin-red-light .main-header .navbar .nav .open>a:hover,.skin-red-light .main-header .navbar .nav .open>a:focus,.skin-red-light .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-red-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-red-light .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-red-light .main-header .navbar .sidebar-toggle{color:#fff}.skin-red-light .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red-light .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-red-light .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red-light .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red-light .main-header .logo{background-color:#dd4b39;color:#fff;border-bottom:0 solid transparent}.skin-red-light .main-header .logo:hover{background-color:#dc4735}.skin-red-light .main-header li.user-header{background-color:#dd4b39}.skin-red-light .content-header{background:transparent}.skin-red-light .wrapper,.skin-red-light .main-sidebar,.skin-red-light .left-side{background-color:#f9fafc}.skin-red-light .content-wrapper,.skin-red-light .main-footer{border-left:1px solid #d2d6de}.skin-red-light .user-panel>.info,.skin-red-light .user-panel>.info>a{color:#444}.skin-red-light .sidebar-menu>li{-webkit-transition:border-left-color .3s ease;-o-transition:border-left-color .3s ease;transition:border-left-color .3s ease}.skin-red-light .sidebar-menu>li.header{color:#848484;background:#f9fafc}.skin-red-light .sidebar-menu>li>a{border-left:3px solid transparent;font-weight:600}.skin-red-light .sidebar-menu>li:hover>a,.skin-red-light .sidebar-menu>li.active>a{color:#000;background:#f4f4f5}.skin-red-light .sidebar-menu>li.active{border-left-color:#dd4b39}.skin-red-light .sidebar-menu>li.active>a{font-weight:600}.skin-red-light .sidebar-menu>li>.treeview-menu{background:#f4f4f5}.skin-red-light .sidebar a{color:#444}.skin-red-light .sidebar a:hover{text-decoration:none}.skin-red-light .treeview-menu>li>a{color:#777}.skin-red-light .treeview-menu>li.active>a,.skin-red-light .treeview-menu>li>a:hover{color:#000}.skin-red-light .treeview-menu>li.active>a{font-weight:600}.skin-red-light .sidebar-form{border-radius:3px;border:1px solid #d2d6de;margin:10px 10px}.skin-red-light .sidebar-form input[type="text"],.skin-red-light .sidebar-form .btn{box-shadow:none;background-color:#fff;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-red-light .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red-light .sidebar-form input[type="text"]:focus,.skin-red-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red-light .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red-light .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}@media (min-width:768px){.skin-red-light.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{border-left:1px solid #d2d6de}}
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/skins/skin-red.min.css:
--------------------------------------------------------------------------------
1 | .skin-red .main-header .navbar{background-color:#dd4b39}.skin-red .main-header .navbar .nav>li>a{color:#fff}.skin-red .main-header .navbar .nav>li>a:hover,.skin-red .main-header .navbar .nav>li>a:active,.skin-red .main-header .navbar .nav>li>a:focus,.skin-red .main-header .navbar .nav .open>a,.skin-red .main-header .navbar .nav .open>a:hover,.skin-red .main-header .navbar .nav .open>a:focus,.skin-red .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-red .main-header .navbar .sidebar-toggle{color:#fff}.skin-red .main-header .navbar .sidebar-toggle:hover{background-color:#d73925}@media (max-width:767px){.skin-red .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-red .main-header .navbar .dropdown-menu li a{color:#fff}.skin-red .main-header .navbar .dropdown-menu li a:hover{background:#d73925}}.skin-red .main-header .logo{background-color:#d73925;color:#fff;border-bottom:0 solid transparent}.skin-red .main-header .logo:hover{background-color:#d33724}.skin-red .main-header li.user-header{background-color:#dd4b39}.skin-red .content-header{background:transparent}.skin-red .wrapper,.skin-red .main-sidebar,.skin-red .left-side{background-color:#222d32}.skin-red .user-panel>.info,.skin-red .user-panel>.info>a{color:#fff}.skin-red .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-red .sidebar-menu>li>a{border-left:3px solid transparent}.skin-red .sidebar-menu>li:hover>a,.skin-red .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#dd4b39}.skin-red .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-red .sidebar a{color:#b8c7ce}.skin-red .sidebar a:hover{text-decoration:none}.skin-red .treeview-menu>li>a{color:#8aa4af}.skin-red .treeview-menu>li.active>a,.skin-red .treeview-menu>li>a:hover{color:#fff}.skin-red .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-red .sidebar-form input[type="text"],.skin-red .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-red .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-red .sidebar-form input[type="text"]:focus,.skin-red .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-red .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-red .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/static/template04/skins/skin-yellow.min.css:
--------------------------------------------------------------------------------
1 | .skin-yellow .main-header .navbar{background-color:#f39c12}.skin-yellow .main-header .navbar .nav>li>a{color:#fff}.skin-yellow .main-header .navbar .nav>li>a:hover,.skin-yellow .main-header .navbar .nav>li>a:active,.skin-yellow .main-header .navbar .nav>li>a:focus,.skin-yellow .main-header .navbar .nav .open>a,.skin-yellow .main-header .navbar .nav .open>a:hover,.skin-yellow .main-header .navbar .nav .open>a:focus,.skin-yellow .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-yellow .main-header .navbar .sidebar-toggle{color:#fff}.skin-yellow .main-header .navbar .sidebar-toggle:hover{background-color:#e08e0b}@media (max-width:767px){.skin-yellow .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-yellow .main-header .navbar .dropdown-menu li a{color:#fff}.skin-yellow .main-header .navbar .dropdown-menu li a:hover{background:#e08e0b}}.skin-yellow .main-header .logo{background-color:#e08e0b;color:#fff;border-bottom:0 solid transparent}.skin-yellow .main-header .logo:hover{background-color:#db8b0b}.skin-yellow .main-header li.user-header{background-color:#f39c12}.skin-yellow .content-header{background:transparent}.skin-yellow .wrapper,.skin-yellow .main-sidebar,.skin-yellow .left-side{background-color:#222d32}.skin-yellow .user-panel>.info,.skin-yellow .user-panel>.info>a{color:#fff}.skin-yellow .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-yellow .sidebar-menu>li>a{border-left:3px solid transparent}.skin-yellow .sidebar-menu>li:hover>a,.skin-yellow .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#f39c12}.skin-yellow .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-yellow .sidebar a{color:#b8c7ce}.skin-yellow .sidebar a:hover{text-decoration:none}.skin-yellow .treeview-menu>li>a{color:#8aa4af}.skin-yellow .treeview-menu>li.active>a,.skin-yellow .treeview-menu>li>a:hover{color:#fff}.skin-yellow .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-yellow .sidebar-form input[type="text"],.skin-yellow .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-yellow .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-yellow .sidebar-form input[type="text"]:focus,.skin-yellow .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-yellow .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-yellow .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/template/01/nav.jsp:
--------------------------------------------------------------------------------
1 | <%@ page contentType="text/html; charset=utf-8" %>
2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3 | <%--
4 | ~ Copyright (c) 2014.
5 | ~ Author WangJun
6 | ~ Email wangjuntytl@163.com
7 | --%>
8 |
9 | <%--导航栏--%>
10 |
36 |
37 |
--------------------------------------------------------------------------------
/task-ops/src/main/webapp/template/01/pageFooter.jsp:
--------------------------------------------------------------------------------
1 | <%@ page contentType="text/html; charset=utf-8" %>
2 |
3 |
4 |
6 |
7 |