mirror of
https://github.com/PowerJob/PowerJob.git
synced 2025-07-17 00:00:04 +08:00
Compare commits
801 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
5d82b7cc5c | ||
|
f506ba8956 | ||
|
8166b78e68 | ||
|
730982b085 | ||
|
f6a8666031 | ||
|
e6264fc9a4 | ||
|
dc62c1b992 | ||
|
c627776764 | ||
|
aefa9290c9 | ||
|
fdd80f6cf9 | ||
|
7333ee3951 | ||
|
92ddc6af4d | ||
|
508127426f | ||
|
57627305fa | ||
|
4e84bc60d7 | ||
|
4fe2d7fdf1 | ||
|
f44bd43d13 | ||
|
e912e2c31d | ||
|
f9dd8d7713 | ||
|
0bb069fa5b | ||
|
f0b2fbb5b7 | ||
|
7443edf735 | ||
|
1383e48fec | ||
|
243f7bb179 | ||
|
827bcd2502 | ||
|
8f3981dd09 | ||
|
9bab361618 | ||
|
01e15bda39 | ||
|
0bf95cf419 | ||
|
f2bed56544 | ||
|
85f5faaaac | ||
|
44ef76328b | ||
|
5c49b8d8dd | ||
|
944b06ee82 | ||
|
a35573544c | ||
|
fea1974014 | ||
|
4527454a7c | ||
|
a261b864ca | ||
|
4f5ea6f897 | ||
|
0a1191572e | ||
|
605497b36d | ||
|
3e0088870a | ||
|
a1dad6c39e | ||
|
6426424401 | ||
|
1774680792 | ||
|
29e0b2deb0 | ||
|
eb4d7ab8eb | ||
|
e711ed7251 | ||
|
53be566173 | ||
|
bee4795027 | ||
|
84b90a366c | ||
|
c04cb08390 | ||
|
4507a6a883 | ||
|
3edaae67dd | ||
|
bb99ec9d04 | ||
|
54fadf6368 | ||
|
1e092bb866 | ||
|
6a59f50b96 | ||
|
9b5916daf3 | ||
|
5e7751f092 | ||
|
e21b171b98 | ||
|
a9d8a680dc | ||
|
b822a685f4 | ||
|
dd3a17275f | ||
|
89e7ef8b40 | ||
|
32cecc59e9 | ||
|
5be7b24f4b | ||
|
1a2df5e616 | ||
|
075ecd8a84 | ||
|
02304fe921 | ||
|
b3abb461db | ||
|
d44131128e | ||
|
f4c0a0309f | ||
|
9046a8bfcf | ||
|
9d95d4ce04 | ||
|
86ec85331a | ||
|
fb1159e1b5 | ||
|
9c0731f20d | ||
|
bd725aac15 | ||
|
c35ae19ba8 | ||
|
c11d544afe | ||
|
e64ad0f74d | ||
|
07e0e17ec0 | ||
|
37ef35bd80 | ||
|
4046ea39b5 | ||
|
815d44ef7e | ||
|
c717fd3fb8 | ||
|
cf4ed93812 | ||
|
dda79439ca | ||
|
7437ad6067 | ||
|
12e2f83764 | ||
|
a750d0c55c | ||
|
d1d0407046 | ||
|
9dbd470c5a | ||
|
5e1f7e2d11 | ||
|
3ea089eaee | ||
|
7b7582dd91 | ||
|
686189e6ca | ||
|
9419340829 | ||
|
6539c66226 | ||
|
c350607762 | ||
|
31a7690844 | ||
|
05c22a5dc5 | ||
|
919a5c3b35 | ||
|
841c7891c8 | ||
|
3fdcc1e599 | ||
|
e18b9a8962 | ||
|
cf8153ae39 | ||
|
a1c12bf1c7 | ||
|
0caa854409 | ||
|
cda55c918b | ||
|
4793c19af6 | ||
|
78b58d02e8 | ||
|
ea919b102f | ||
|
599d710e27 | ||
|
ab7a398f61 | ||
|
01d7247efa | ||
|
b29e265e42 | ||
|
61aecc6354 | ||
|
6de5e83a2f | ||
|
88f7a06596 | ||
|
98fc4d3320 | ||
|
6842fb6a7b | ||
|
debc2e0abb | ||
|
f3dd56bf54 | ||
|
e63dc91643 | ||
|
4be6a139dd | ||
|
1ba74bf0af | ||
|
ff84d46713 | ||
|
d61d85abd4 | ||
|
23d94ed46f | ||
|
8f3803bda6 | ||
|
592dff8d75 | ||
|
9b7c237cf0 | ||
|
9b3a3cd586 | ||
|
966f09c034 | ||
|
4a9f38c760 | ||
|
b96768208b | ||
|
1545733012 | ||
|
fa8b4f2b62 | ||
|
882392a5e5 | ||
|
c875ba3d37 | ||
|
a138f9c8cc | ||
|
360f105c01 | ||
|
3544f76aaa | ||
|
8de1c47971 | ||
|
5dbceb7ce4 | ||
|
93dadab832 | ||
|
9ab2e92934 | ||
|
0d359b8a8e | ||
|
c91240c1b8 | ||
|
b14b49f75e | ||
|
74a92622a3 | ||
|
b5085e09f1 | ||
|
91abbc03d9 | ||
|
bdcc9b131d | ||
|
58e542c69a | ||
|
15fa1abd91 | ||
|
c08b4f1858 | ||
|
89b35c8495 | ||
|
73ebe83c05 | ||
|
ad08406d0b | ||
|
37a62549db | ||
|
c50a3edebf | ||
|
09b15dfbc1 | ||
|
6bcc275a70 | ||
|
88ebd5e042 | ||
|
df5e259e54 | ||
|
570ea0487b | ||
|
dd32916637 | ||
|
c3ce46aee9 | ||
|
d03247ea03 | ||
|
1c70bbc670 | ||
|
b251df4c35 | ||
|
f0514ac65f | ||
|
236d0a7f3b | ||
|
fc57226d3a | ||
|
5e9935fed4 | ||
|
d3140d0501 | ||
|
7318fed73a | ||
|
67a22e8b7e | ||
|
8aaa602082 | ||
|
1adc25308f | ||
|
00228f3b3e | ||
|
c3c735e5f1 | ||
|
df7ceb7ba5 | ||
|
5da0c694c3 | ||
|
5cfd0f8e74 | ||
|
e2887a12f6 | ||
|
388581c321 | ||
|
8953ecc74f | ||
|
8ecc5768c7 | ||
|
a7394e518c | ||
|
174696066d | ||
|
47b050aba2 | ||
|
46165ccd97 | ||
|
b9bd8079f2 | ||
|
1a40447b23 | ||
|
e2f5ca440f | ||
|
b71edc1f26 | ||
|
2a87a24980 | ||
|
93b01191d0 | ||
|
aa65884b3f | ||
|
4b79bd73bb | ||
|
0a76d057ac | ||
|
7b003ed895 | ||
|
70a696aaa8 | ||
|
5011ea983b | ||
|
a93602f845 | ||
|
805046dccb | ||
|
0772b41fac | ||
|
1fc240ab27 | ||
|
36b439603c | ||
|
0bb46be9d0 | ||
|
4eeda2c662 | ||
|
fcca0c0c94 | ||
|
06c4e085cb | ||
|
81752dd26f | ||
|
93d44ea07d | ||
|
a90cf82974 | ||
|
e36ac8bc59 | ||
|
3fcd99e364 | ||
|
74ef8f1d23 | ||
|
40192486c5 | ||
|
d45cb0712c | ||
|
5985c04997 | ||
|
5ddaa33f47 | ||
|
d78d139276 | ||
|
43dfc9a265 | ||
|
3aa42819e4 | ||
|
8ea4a5b260 | ||
|
34352a1eea | ||
|
2d0dcf6c7b | ||
|
cdf416d693 | ||
|
8c32c775da | ||
|
369ebdab0b | ||
|
e01770adc7 | ||
|
42823b8bdd | ||
|
9f2f68344c | ||
|
3f7d4328e9 | ||
|
421705e1bc | ||
|
69dc1c50aa | ||
|
b89ac389fd | ||
|
a5e3e829b5 | ||
|
7d947038eb | ||
|
c8a456f56d | ||
|
afa54e7958 | ||
|
39893b1e92 | ||
|
95a1f43994 | ||
|
d7c494e463 | ||
|
5ea57eebcc | ||
|
ae36ccf75a | ||
|
d5b4faa49c | ||
|
b0fae5edf8 | ||
|
1c60f17b1b | ||
|
d9b1272802 | ||
|
31d9b5b7e6 | ||
|
19a3f2fbed | ||
|
c9f5fb3f51 | ||
|
a25eac67c7 | ||
|
fb2046649e | ||
|
54beb3b2d1 | ||
|
2bd2ceca8e | ||
|
8df74b9670 | ||
|
6921cfdcf5 | ||
|
da4aa8a9fe | ||
|
a9f81d260c | ||
|
7b56393aee | ||
|
1b1efe6b80 | ||
|
3bfe58abd2 | ||
|
55e259bcf7 | ||
|
bc08b76d23 | ||
|
5f75dbe9fc | ||
|
e73675ce09 | ||
|
8e94976cdd | ||
|
b8199bf036 | ||
|
6c21c7864a | ||
|
dc61bb4648 | ||
|
afdf4a7dc2 | ||
|
789bcb5d10 | ||
|
5b78204beb | ||
|
dca97010c7 | ||
|
63a5e2b458 | ||
|
17b842a2a2 | ||
|
4a41e322ab | ||
|
e26f2df2d0 | ||
|
571b7cf3f2 | ||
|
4fece7be40 | ||
|
bfb9c68590 | ||
|
25c6a9a6d6 | ||
|
b746aa1859 | ||
|
e74fc2d138 | ||
|
dedefd5a6d | ||
|
b013fbfefd | ||
|
5a14b300f9 | ||
|
3892c38785 | ||
|
8e96fdacc6 | ||
|
503e9db5c2 | ||
|
f6a6914f91 | ||
|
847cf23738 | ||
|
16f5e67cf0 | ||
|
74358bca8d | ||
|
7eea92bfc7 | ||
|
5b94247daf | ||
|
2020f72905 | ||
|
f0da89503e | ||
|
d46a6de26e | ||
|
43df09bb38 | ||
|
0400eceab1 | ||
|
38d6b16c74 | ||
|
3d5a5ac342 | ||
|
4d2e037107 | ||
|
cc7a63c69f | ||
|
57450a98ad | ||
|
44e6ea2373 | ||
|
1ca5fed9cf | ||
|
2982410d80 | ||
|
fbd75a6ec7 | ||
|
d6f3ae6c44 | ||
|
59121684a8 | ||
|
c47fd69859 | ||
|
ccbe11ed0e | ||
|
30abf08703 | ||
|
1b3134291c | ||
|
2c51e0601d | ||
|
cd7a743097 | ||
|
2afb20df0b | ||
|
0d29b6369a | ||
|
24b4cc4eb5 | ||
|
50b4ca3cca | ||
|
7b9ee74c21 | ||
|
8b9d6df172 | ||
|
676388a988 | ||
|
b0b2c24571 | ||
|
5d3bfedf5d | ||
|
d73b8e21e6 | ||
|
94a0e2fa42 | ||
|
79cde85256 | ||
|
fe03b8faab | ||
|
9f6d421ed2 | ||
|
da04e4b048 | ||
|
a1beb44ccf | ||
|
4b2d9d4d74 | ||
|
432adeb00f | ||
|
f2b9ae222a | ||
|
af8fbb0167 | ||
|
d12ac4d6cd | ||
|
e6a171d775 | ||
|
2606440f44 | ||
|
d3bd22302f | ||
|
2c31e81c5f | ||
|
87a1a1d7c1 | ||
|
268f5dd5c7 | ||
|
eb6b0c35a5 | ||
|
0c8e339140 | ||
|
68a9cc52e2 | ||
|
31d2283f99 | ||
|
c6d90be839 | ||
|
4356c5566d | ||
|
84ef2fd120 | ||
|
d3b8c4e353 | ||
|
3f95ee8a33 | ||
|
5ba4ce5457 | ||
|
39eb79de54 | ||
|
5189634b60 | ||
|
eb195cf891 | ||
|
b9222b8594 | ||
|
987aa966a0 | ||
|
75e5c7049f | ||
|
33539857f4 | ||
|
a9936b8dba | ||
|
757b994176 | ||
|
e6c94af599 | ||
|
3bcfbd8e9f | ||
|
0541216944 | ||
|
50b68e82bd | ||
|
daaaa15b94 | ||
|
195984bb95 | ||
|
7867b07d9c | ||
|
223fac9828 | ||
|
1b710c1332 | ||
|
dc98f5f37a | ||
|
c6009c8b5e | ||
|
ce0290ea03 | ||
|
1301da0d7d | ||
|
6eb5966e96 | ||
|
db7f5855e1 | ||
|
fe1fad6a7b | ||
|
7feb25cf8a | ||
|
cded964bcd | ||
|
5d5b1e3854 | ||
|
5b68b4dc75 | ||
|
2f62f448a8 | ||
|
cb72fcb08a | ||
|
60209ebbc1 | ||
|
050190ba89 | ||
|
54db609d32 | ||
|
806747d88c | ||
|
6de2be72ef | ||
|
4bc94dd465 | ||
|
a5b46f6a47 | ||
|
5a73e6ad91 | ||
|
91b48c0a5e | ||
|
78d793d28e | ||
|
653dcb4a92 | ||
|
ce555ad18f | ||
|
e5d3139990 | ||
|
b2b8241295 | ||
|
f20a849a93 | ||
|
f3c7ed8baf | ||
|
483227f840 | ||
|
45f7b17e14 | ||
|
3823b3bc56 | ||
|
a39751818f | ||
|
ec47f5a8c5 | ||
|
74b6acc927 | ||
|
dc90f272c7 | ||
|
e501cb9dfa | ||
|
a4a41c4ab7 | ||
|
3842acf952 | ||
|
3ffaf382c7 | ||
|
ca063803db | ||
|
be2c5ea20e | ||
|
2a3b9323a6 | ||
|
12ff1335f2 | ||
|
112628f386 | ||
|
42fa628a61 | ||
|
65f2a58d2f | ||
|
5acb8f82e7 | ||
|
a32d7cebb5 | ||
|
5b223d23ad | ||
|
fd562d8ea0 | ||
|
e6d32c9a05 | ||
|
fadf2ce14e | ||
|
510b5ab546 | ||
|
a77ba8084e | ||
|
1b9d8331a1 | ||
|
ac2b28bb5f | ||
|
74f70cd58b | ||
|
5450ac00db | ||
|
2db0f05feb | ||
|
3466ff3f05 | ||
|
d531bf3a22 | ||
|
3b73a750e6 | ||
|
3869b115ce | ||
|
614349370a | ||
|
48ac446014 | ||
|
ac1b1fe0c8 | ||
|
dfd1fd069b | ||
|
22db37cad9 | ||
|
22522c099d | ||
|
eaf6dcad4f | ||
|
b6de5aa563 | ||
|
519213ad4a | ||
|
ce369b3e30 | ||
|
29a50ed89a | ||
|
2a76e7d043 | ||
|
cca9c5421e | ||
|
e23825c399 | ||
|
a7e3c05f6c | ||
|
5b865fe49b | ||
|
88bc28140f | ||
|
a0cc5670d4 | ||
|
5080796c6f | ||
|
ad1a7227d6 | ||
|
d0e95c2129 | ||
|
03165bf5e4 | ||
|
bdd9b978f9 | ||
|
54524553c1 | ||
|
0b5a404cf4 | ||
|
e1c4946a73 | ||
|
3566569dc5 | ||
|
08711f93d0 | ||
|
5ed6eac38a | ||
|
0c4eb3834a | ||
|
a9a0422de1 | ||
|
812d71f090 | ||
|
7539faffff | ||
|
88b92e2994 | ||
|
2e1c585b5e | ||
|
3923937f6c | ||
|
8909584976 | ||
|
abf266b7f8 | ||
|
1d34547f45 | ||
|
56447596f7 | ||
|
8488a10465 | ||
|
b60c236824 | ||
|
d87c358743 | ||
|
5791b43ac6 | ||
|
d4eb8e3303 | ||
|
9c30e5ee83 | ||
|
8aa5140265 | ||
|
d7c0d12a30 | ||
|
9194641c6f | ||
|
4b14be8321 | ||
|
d996b34a54 | ||
|
c15cefc447 | ||
|
8663f3b79f | ||
|
ac8e96508c | ||
|
d799586ce9 | ||
|
e585ba5a19 | ||
|
62d682fbd5 | ||
|
fb6e57a75c | ||
|
75c88c32ed | ||
|
0aa06d1ae6 | ||
|
973322370a | ||
|
49c7d18c00 | ||
|
4fccc81697 | ||
|
e094c22952 | ||
|
6ae809617b | ||
|
cbcd5dcca7 | ||
|
7a471a3917 | ||
|
584b20ae9b | ||
|
f955ae2f61 | ||
|
c8a1f536c3 | ||
|
7527b31ece | ||
|
4e9c1f98b7 | ||
|
12d0d4dbb0 | ||
|
17439536f0 | ||
|
9949e23bc4 | ||
|
4d236153de | ||
|
a0f76f7ba9 | ||
|
5f0865129e | ||
|
c31f10b3c1 | ||
|
0e5873ca05 | ||
|
cfb05d9871 | ||
|
98330846c3 | ||
|
15f48304b2 | ||
|
88caf22c9f | ||
|
93c19eae82 | ||
|
f5afff56c4 | ||
|
0adb16011c | ||
|
ddabdf2187 | ||
|
e767ad1043 | ||
|
4399f99c42 | ||
|
f8ef896a65 | ||
|
0a854cd276 | ||
|
fe439721d0 | ||
|
d8811c7d77 | ||
|
d29f0651e2 | ||
|
145d525b29 | ||
|
ab8c8b5f0f | ||
|
0febeea298 | ||
|
50635faf53 | ||
|
2cb33a7019 | ||
|
d6b72afd19 | ||
|
2e0797007c | ||
|
dff1fa4938 | ||
|
fb3673116b | ||
|
0f6ac91080 | ||
|
f3b4e91745 | ||
|
3ce47382d8 | ||
|
9dffb49918 | ||
|
67f9cbab5e | ||
|
3f6585cfda | ||
|
1273b16caf | ||
|
0fc9978385 | ||
|
f1baef7de4 | ||
|
2c8d1345cb | ||
|
5a9a5c6910 | ||
|
93158ba19b | ||
|
5834963fdd | ||
|
0f1d760dbe | ||
|
86b584be2f | ||
|
1d67e97b45 | ||
|
30d0d7d338 | ||
|
4c89a1e69c | ||
|
d07ed2b013 | ||
|
48860e3172 | ||
|
87ed304737 | ||
|
f4d7459f63 | ||
|
65e0d118c3 | ||
|
2ed0391d15 | ||
|
d20cbdb844 | ||
|
375b70dd40 | ||
|
afff77b540 | ||
|
e6127f1dba | ||
|
38929bff6d | ||
|
6a25bb57e4 | ||
|
b690d9c594 | ||
|
f81b785c0f | ||
|
3cf4807ca3 | ||
|
59d4df1422 | ||
|
cc9d804e84 | ||
|
30f2d2404e | ||
|
17cb9ea626 | ||
|
bbc1cce627 | ||
|
7579d02693 | ||
|
572ad44fb1 | ||
|
51d12dc6b4 | ||
|
dcb6b5ee24 | ||
|
b608bb9908 | ||
|
f633f9ae57 | ||
|
a0564b7922 | ||
|
5b09865b42 | ||
|
27ebd42c8e | ||
|
218d974122 | ||
|
59e3fee086 | ||
|
0c424b52df | ||
|
aee69a4167 | ||
|
b3ca7fd670 | ||
|
7575bbd4e1 | ||
|
5f1ab82f0e | ||
|
8f9e53ed83 | ||
|
21291b34cb | ||
|
bf5f6ef0db | ||
|
44ae97d6d8 | ||
|
da6eb3705b | ||
|
9a6047ad9c | ||
|
519d370445 | ||
|
ef384b5574 | ||
|
539d31007c | ||
|
cea2c0cc87 | ||
|
79b30f882d | ||
|
6d5225beab | ||
|
540849524d | ||
|
84d00ee580 | ||
|
a8e284ccbe | ||
|
611f8773e8 | ||
|
b197dc4286 | ||
|
ec9519a6b2 | ||
|
3d1c907104 | ||
|
6dc20eee7d | ||
|
b89c129e2b | ||
|
bd9224a805 | ||
|
823a47303b | ||
|
79a61454f3 | ||
|
91bb28abbb | ||
|
449608293c | ||
|
5fd4b9ae9d | ||
|
ed94bef458 | ||
|
e24f20f5ba | ||
|
2e488b5837 | ||
|
daf42be5cb | ||
|
eac7ce7b27 | ||
|
d6d461c77e | ||
|
fa3981d167 | ||
|
783ea4f67f | ||
|
9748190a8a | ||
|
6671bcf6f7 | ||
|
c3cc8aef4c | ||
|
4ee6300c6a | ||
|
11b712332d | ||
|
814d4321a1 | ||
|
fd36f2f8e1 | ||
|
6d9af1cff0 | ||
|
56993335e3 | ||
|
e1fc805a0b | ||
|
16a5f8efb6 | ||
|
83ac13b221 | ||
|
770f30dd05 | ||
|
83f6cf50a7 | ||
|
c17da02da5 | ||
|
7441c61313 | ||
|
dfbf9ec137 | ||
|
5586d48f93 | ||
|
ee9ed3c099 | ||
|
b4288225a0 | ||
|
a1a5ade215 | ||
|
eb87c329bb | ||
|
ea5cbfe8c4 | ||
|
a575b65320 | ||
|
eda39a6372 | ||
|
0f1e17e862 | ||
|
57501075de | ||
|
d978f84a60 | ||
|
3d1dc68928 | ||
|
64b9673a5c | ||
|
b24e0d2682 | ||
|
75d922d4a9 | ||
|
e97bdc71c7 | ||
|
ef3f322fff | ||
|
d06e5bc029 | ||
|
0f3cd48527 | ||
|
5b41da1473 | ||
|
4a4ef9ba13 | ||
|
3cc195ee33 | ||
|
bb11209d45 | ||
|
5ff56f8a41 | ||
|
7616890050 | ||
|
80d2709104 | ||
|
c199945840 | ||
|
f3048caaf0 | ||
|
2c3e35a742 | ||
|
02eed5e15e | ||
|
e3ef52fc0a | ||
|
1af361444d | ||
|
c4098a60e7 | ||
|
b642e1b39b | ||
|
2066f5d1da | ||
|
cce26511d8 | ||
|
cdaea08ba7 | ||
|
fb29d8013b | ||
|
2035bd6544 | ||
|
9e349a202a | ||
|
74fc5edb1f | ||
|
5dbc8db849 | ||
|
b71d167afd | ||
|
4951ccad09 | ||
|
1e51a5161f | ||
|
144020a710 | ||
|
b23ae334d3 | ||
|
119de1fb44 | ||
|
3cb9ddf31f | ||
|
dd66c8fd31 | ||
|
01e7dd41c7 | ||
|
b044784e6a | ||
|
e429c6f59e | ||
|
62aeb9c080 | ||
|
76eaabb42f | ||
|
293bc64ffa | ||
|
1c52809ebb | ||
|
895e69f043 | ||
|
0912964ec3 | ||
|
64c36d402a | ||
|
7acc1e67e3 | ||
|
bd8db1b9df | ||
|
3bd37525ca | ||
|
2ab5ac6aa0 | ||
|
bc58272c85 | ||
|
9d10e939a1 | ||
|
2ac9cb44e9 | ||
|
8d6d7c927d | ||
|
515ce9bce2 | ||
|
2ecbc2c205 | ||
|
37cf53e0a9 | ||
|
374bae9fc1 | ||
|
5f3827b8e7 | ||
|
f34f903947 | ||
|
5feaf6106e | ||
|
b97c26c78b | ||
|
078db73bce | ||
|
2da5fc624b | ||
|
b1b8e1de95 | ||
|
d5ab77ddbd | ||
|
36e258012e | ||
|
281c53ad63 | ||
|
d4a7aa68b1 | ||
|
d69171afa5 | ||
|
1384e1a886 | ||
|
b248f76d32 | ||
|
f507d340a2 | ||
|
43ca05883a | ||
|
9e6ba33f90 | ||
|
b6173967bb | ||
|
6fc5c65825 | ||
|
6c3c6695e4 | ||
|
dfd2106a3f | ||
|
85b8d004e4 | ||
|
52ea3fb80d | ||
|
24cff5b6ec | ||
|
6a85995937 | ||
|
3776d4ad84 | ||
|
0daa097d20 | ||
|
9a661aa177 | ||
|
05181c34ec | ||
|
ead9f08e52 | ||
|
3ecefd22cb | ||
|
0e77a23e76 | ||
|
269d64065c | ||
|
1b68fdb7d7 | ||
|
83dae8ddd3 | ||
|
2b7936b39b | ||
|
6ae24ac9ed | ||
|
ef881cfcac | ||
|
5329fba6b0 | ||
|
d4af8138d0 | ||
|
4f3b6057b6 | ||
|
73a5a724ec | ||
|
e8ada3789f | ||
|
c176a447e7 | ||
|
11054e9761 | ||
|
2d989d2b0b | ||
|
12162f2955 | ||
|
0de6a9f4f5 | ||
|
c40774d578 | ||
|
9f2d3134d8 | ||
|
0095d78615 | ||
|
977b8bfd4b | ||
|
76e5a41881 | ||
|
35f0991f03 | ||
|
4eb53990f4 | ||
|
ca6b02d19f | ||
|
e311e7c500 | ||
|
be43839d73 | ||
|
9822e8a10f | ||
|
3acbd0bcf5 | ||
|
ee80ae76a8 | ||
|
d799c0f2bd | ||
|
3029673612 | ||
|
ff81ac4485 | ||
|
8b93ca93eb | ||
|
1a8cc2a696 | ||
|
9db9d0d01f | ||
|
b4f92bbc25 | ||
|
a4f768e46c | ||
|
e300885839 | ||
|
6ce5765ff4 | ||
|
f104b34d2c | ||
|
efb4486a43 | ||
|
143663e333 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
github: #[KFCFans]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
open_collective: powerjob
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
|
27
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
27
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
## What is the purpose of the change
|
||||
|
||||
For example: Making PowerJob better
|
||||
|
||||
## Brief changelog
|
||||
|
||||
It is best to associate an existing issue
|
||||
|
||||
## Verifying this change
|
||||
|
||||
Do I need to test?
|
||||
Has testing been completed?
|
||||
Test method?
|
||||
|
||||
Follow this checklist to help us incorporate your contribution quickly and easily. Notice, `it would be helpful if you could finish the following 3 checklist before request the community to review your PR`.
|
||||
|
||||
- [x] Make sure there is a [Github issue](https://github.com/PowerJob/PowerJob/issues) filed for the change (usually before you start working on it). Trivial changes like typos do not require a Github issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
|
||||
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [x] Follow the git commit specification
|
||||
* feat: xxx -> The feat type is used to identify production changes related to new backward-compatible abilities or functionality.
|
||||
* perf: xxx -> The perf type is used to identify production changes related to backward-compatible performance improvements.
|
||||
* fix: xxx -> The fix type is used to identify production changes related to backward-compatible bug fixes.
|
||||
* docs: xxx -> The docs type is used to identify documentation changes related to the project - whether intended externally for the end users (in case of a library) or internally for the developers.
|
||||
* test: xxx -> The test type is used to identify development changes related to tests - such as refactoring existing tests or adding new tests.
|
||||
* refactor: xxx -> The refactor type is used to identify development changes related to modifying the codebase, which neither adds a feature nor fixes a bug - such as removing redundant code, simplifying the code, renaming variables, etc.
|
||||
|
||||
|
30
.github/workflows/docker-image.yml
vendored
30
.github/workflows/docker-image.yml
vendored
@ -1,30 +0,0 @@
|
||||
name: Docker Image CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build the Docker image
|
||||
run: mvn clean package -Pdev -DskipTests -U -e -pl powerjob-server,powerjob-worker-agent -am && /bin/cp -rf powerjob-server/target/*.jar powerjob-server/docker/powerjob-server.jar && /bin/cp -rf powerjob-worker-agent/target/*.jar powerjob-worker-agent/powerjob-agent.jar
|
||||
- uses: docker/build-push-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
repository: tjqq/powerjob-server
|
||||
tags: latest
|
||||
path: powerjob-server/docker/
|
||||
- uses: docker/build-push-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
repository: tjqq/powerjob-agent
|
||||
tags: latest
|
||||
path: powerjob-worker-agent/
|
68
.github/workflows/docker_publish.yml
vendored
Normal file
68
.github/workflows/docker_publish.yml
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
name: build_docker
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
jobs:
|
||||
build_docker:
|
||||
name: Build docker
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build Maven Project
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'temurin'
|
||||
- name: Publish package
|
||||
run: mvn clean package -Pdev -DskipTests -U -e && /bin/cp -rf powerjob-server/powerjob-server-starter/target/*.jar powerjob-server/docker/powerjob-server.jar && /bin/cp -rf powerjob-worker-agent/target/*.jar powerjob-worker-agent/powerjob-agent.jar && /bin/cp -rf powerjob-worker-samples/target/*.jar powerjob-worker-samples/powerjob-worker-samples.jar
|
||||
|
||||
# Login
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build And Push [powerjob-server]
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: powerjob-server/docker/
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
tjqq/powerjob-server:latest
|
||||
powerjob/powerjob-server:latest
|
||||
tjqq/powerjob-server:${{ github.ref_name }}
|
||||
powerjob/powerjob-server:${{ github.ref_name }}
|
||||
|
||||
- name: Build And Push [powerjob-agent]
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: powerjob-worker-agent/
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
tjqq/powerjob-agent:latest
|
||||
powerjob/powerjob-agent:latest
|
||||
tjqq/powerjob-agent:${{ github.ref_name }}
|
||||
powerjob/powerjob-agent:${{ github.ref_name }}
|
||||
|
||||
- name: Build And Push [powerjob-worker-samples]
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: powerjob-worker-samples/
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
tjqq/powerjob-worker-samples:latest
|
||||
powerjob/powerjob-worker-samples:latest
|
||||
tjqq/powerjob-worker-samples:${{ github.ref_name }}
|
||||
powerjob/powerjob-worker-samples:${{ github.ref_name }}
|
38
.github/workflows/maven.yml
vendored
38
.github/workflows/maven.yml
vendored
@ -1,38 +0,0 @@
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Java CI with Maven
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Build with Maven
|
||||
run: mvn -B clean package -Pdev -DskipTests --file pom.xml
|
||||
- name: upload build result
|
||||
run: mkdir staging && cp powerjob-server/target/*.jar staging/powerjob-server.jar && cp powerjob-client/target/*.jar staging/powerjob-client.jar && cp powerjob-worker-agent/target/*.jar staging/powerjob-agent.jar
|
||||
- uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: powerjob-server.jar
|
||||
path: staging/powerjob-server.jar
|
||||
- uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: powerjob-client.jar
|
||||
path: staging/powerjob-client.jar
|
||||
- uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: powerjob-agent.jar
|
||||
path: staging/powerjob-agent.jar
|
28
.github/workflows/maven_build.yml
vendored
Normal file
28
.github/workflows/maven_build.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://docs.github.com/zh/actions/use-cases-and-examples/building-and-testing/building-and-testing-java-with-maven
|
||||
|
||||
name: Java CI with Maven
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'temurin'
|
||||
- run: mvn -B clean package -Pdev -DskipTests --file pom.xml
|
||||
- run: mkdir staging && cp powerjob-server/powerjob-server-starter/target/*.jar staging/powerjob-server.jar && cp powerjob-client/target/*.jar staging/powerjob-client.jar && cp powerjob-worker-agent/target/*.jar staging/powerjob-agent.jar && cp powerjob-worker-spring-boot-starter/target/*.jar staging/powerjob-worker-spring-boot-starter.jar
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Package
|
||||
path: staging
|
||||
|
22
.github/workflows/maven_publish.yml
vendored
Normal file
22
.github/workflows/maven_publish.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
name: Publish package to the Maven Central Repository
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Maven Central Repository
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'temurin'
|
||||
server-id: ossrh
|
||||
server-username: MAVEN_USERNAME
|
||||
server-password: MAVEN_PASSWORD
|
||||
- name: Publish package
|
||||
run: mvn --batch-mode clean deploy -pl powerjob-worker,powerjob-client,powerjob-worker-spring-boot-starter,powerjob-official-processors,powerjob-worker-agent -DskipTests -Prelease -am
|
||||
env:
|
||||
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||
MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
|
8
.gitignore
vendored
8
.gitignore
vendored
@ -35,3 +35,11 @@ build/
|
||||
*.log
|
||||
*/.DS_Store
|
||||
.DS_Store
|
||||
|
||||
.phd
|
||||
.txt
|
||||
.trc
|
||||
*/.phd
|
||||
*/.txt
|
||||
*/.trc
|
||||
powerjob-data/
|
2
LICENSE
2
LICENSE
@ -186,7 +186,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright [2021] [PowerJob]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
109
README.md
109
README.md
@ -1,76 +1,77 @@
|
||||
# English | [简体中文](./README_zhCN.md)
|
||||
|
||||
<p align="center">
|
||||
🏮PowerJob 全体成员祝大家龙年腾飞,新的一年身体健康,万事如意,阖家欢乐,幸福安康!🏮
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/KFCFans/PowerJob/master/others/images/logo.png" alt="PowerJob" title="PowerJob" width="557"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/KFCFans/PowerJob/actions"><img src="https://github.com/KFCFans/PowerJob/workflows/Java%20CI%20with%20Maven/badge.svg?branch=master" alt="actions"></a>
|
||||
<a href="https://search.maven.org/search?q=com.github.kfcfans"><img alt="Maven Central" src="https://img.shields.io/maven-central/v/com.github.kfcfans/powerjob-worker"></a>
|
||||
<a href="https://github.com/KFCFans/PowerJob/releases"><img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/kfcfans/powerjob?color=%23E59866"></a>
|
||||
<a href="https://github.com/KFCFans/PowerJob/blob/master/LICENSE"><img src="https://img.shields.io/github/license/KFCFans/PowerJob" alt="LICENSE"></a>
|
||||
<a href="https://github.com/PowerJob/PowerJob/actions"><img src="https://github.com/PowerJob/PowerJob/workflows/Java%20CI%20with%20Maven/badge.svg?branch=master" alt="actions"></a>
|
||||
<a href="https://central.sonatype.com/search?smo=true&q=powerjob-worker&namespace=tech.powerjob"><img alt="Maven Central" src="https://img.shields.io/maven-central/v/tech.powerjob/powerjob-worker"></a>
|
||||
<a href="https://github.com/PowerJob/PowerJob/releases"><img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/kfcfans/powerjob?color=%23E59866"></a>
|
||||
<a href="https://github.com/PowerJob/PowerJob/blob/master/LICENSE"><img src="https://img.shields.io/github/license/KFCFans/PowerJob" alt="LICENSE"></a>
|
||||
</p>
|
||||
|
||||
PowerJob(原OhMyScheduler)是全新一代分布式调度与计算框架,能让您轻松完成作业的调度与繁杂任务的分布式计算。
|
||||
# 简介
|
||||
### 主要特性
|
||||
* 使用简单:提供前端Web界面,允许开发者可视化地完成调度任务的管理(增、删、改、查)、任务运行状态监控和运行日志查看等功能。
|
||||
* 定时策略完善:支持CRON表达式、固定频率、固定延迟和API四种定时调度策略。
|
||||
* 执行模式丰富:支持单机、广播、Map、MapReduce四种执行模式,其中Map/MapReduce处理器能使开发者寥寥数行代码便获得集群分布式计算的能力。
|
||||
* DAG工作流支持:支持在线配置任务依赖关系,可视化得对任务进行编排,同时还支持上下游任务间的数据传递
|
||||
* 执行器支持广泛:支持Spring Bean、内置/外置Java类、Shell、Python等处理器,应用范围广。
|
||||
* 运维便捷:支持在线日志功能,执行器产生的日志可以在前端控制台页面实时显示,降低debug成本,极大地提高开发效率。
|
||||
* 依赖精简:最小仅依赖关系型数据库(MySQL/Oracle/MS SQLServer...),扩展依赖为MongoDB(用于存储庞大的在线日志)。
|
||||
* 高可用&高性能:调度服务器经过精心设计,一改其他调度框架基于数据库锁的策略,实现了无锁化调度。部署多个调度服务器可以同时实现高可用和性能的提升(支持无限的水平扩展)。
|
||||
* 故障转移与恢复:任务执行失败后,可根据配置的重试策略完成重试,只要执行器集群有足够的计算节点,任务就能顺利完成。
|
||||
[PowerJob](https://github.com/PowerJob/PowerJob) is an open-source distributed computing and job scheduling framework which allows developers to easily schedule tasks in their own application.
|
||||
|
||||
### 适用场景
|
||||
* 有定时执行需求的业务场景:如每天凌晨全量同步数据、生成业务报表等。
|
||||
* 有需要全部机器一同执行的业务场景:如使用广播执行模式清理集群日志。
|
||||
* 有需要分布式处理的业务场景:比如需要更新一大批数据,单机执行耗时非常长,可以使用Map/MapReduce处理器完成任务的分发,调动整个集群加速计算。
|
||||
* 有需要**延迟执行**某些任务的业务场景:比如订单过期处理等。
|
||||
Refer to [PowerJob Introduction](https://www.yuque.com/powerjob/en/introduce) for detailed information.
|
||||
|
||||
### 设计目标
|
||||
PowerJob 的设计目标为企业级的分布式任务调度平台,即成为公司内部的**任务调度中间件**。整个公司统一部署调度中心 powerjob-server,旗下所有业务线应用只需要依赖 `powerjob-worker` 即可接入调度中心获取任务调度与分布式计算能力。
|
||||
# Introduction
|
||||
|
||||
### 在线试用
|
||||
试用地址:[try.powerjob.tech](http://try.powerjob.tech/)
|
||||
试用应用名称:powerjob-agent-test
|
||||
控制台密码:123
|
||||
### Features
|
||||
- **Friendly UI:** [Front-end](http://try.powerjob.tech/#/welcome?appName=powerjob-agent-test&password=123) page is provided and developers can manage their task, monitor the status, check the logs online, etc.
|
||||
|
||||
[建议点击查看试用文档了解相关操作](https://www.yuque.com/powerjob/guidence/hnbskn)
|
||||
- **Abundant Timing Strategies:** Four timing strategies are supported, including CRON expression, fixed rate, fixed delay and OpenAPI which allows you to define your own scheduling policies, such as delaying execution.
|
||||
|
||||
### 同类产品对比
|
||||
| | QuartZ | xxl-job | SchedulerX 2.0 | PowerJob |
|
||||
| -------------- | ------------------------ | ---------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------ |
|
||||
| 定时类型 | CRON | CRON | CRON、固定频率、固定延迟、OpenAPI | **CRON、固定频率、固定延迟、OpenAPI** |
|
||||
| 任务类型 | 内置Java | 内置Java、GLUE Java、Shell、Python等脚本 | 内置Java、外置Java(FatJar)、Shell、Python等脚本 | **内置Java、外置Java(容器)、Shell、Python等脚本** |
|
||||
| 分布式计算 | 无 | 静态分片 | MapReduce动态分片 | **MapReduce动态分片** |
|
||||
| 在线任务治理 | 不支持 | 支持 | 支持 | **支持** |
|
||||
| 日志白屏化 | 不支持 | 支持 | 不支持 | **支持** |
|
||||
| 调度方式及性能 | 基于数据库锁,有性能瓶颈 | 基于数据库锁,有性能瓶颈 | 不详 | **无锁化设计,性能强劲无上限** |
|
||||
| 报警监控 | 无 | 邮件 | 短信 | **WebHook、邮件、钉钉与自定义扩展** |
|
||||
| 系统依赖 | JDBC支持的关系型数据库(MySQL、Oracle...) | MySQL | 人民币 | **任意Spring Data Jpa支持的关系型数据库(MySQL、Oracle...)** |
|
||||
| DAG工作流 | 不支持 | 不支持 | 支持 | **支持** |
|
||||
- **Multiple Execution Mode:** Four execution modes are supported, including stand-alone, broadcast, Map and MapReduce. Distributed computing resource could be utilized in MapReduce mode, try the magic out [here](https://www.yuque.com/powerjob/en/za1d96#9YOnV)!
|
||||
|
||||
- **Workflow(DAG) Support:** Both job dependency management and data communications between jobs are supported.
|
||||
|
||||
# 官方文档
|
||||
**[中文文档](https://www.yuque.com/powerjob/guidence/ztn4i5)**
|
||||
- **Extensive Processor Support:** Developers can write their processors in Java, Shell, Python, and will subsequently support multilingual scheduling via HTTP.
|
||||
|
||||
**[Document](https://www.yuque.com/powerjob/en/xrdoqw)**
|
||||
- **Powerful Disaster Tolerance:** As long as there are enough computing nodes, configurable retry policies make it possible for your task to be executed and finished successfully.
|
||||
|
||||
PS:感谢文档翻译平台[breword](https://www.breword.com/)对本项目英文文档翻译做出的巨大贡献!
|
||||
- **High Availability & High Performance:** PowerJob supports unlimited horizontal expansion. It's easy to achieve high availability and performance by deploying as many PowerJob server and worker nodes.
|
||||
|
||||
# 接入登记
|
||||
[点击进行接入登记,为 PowerJob 的发展贡献自己的力量!](https://github.com/KFCFans/PowerJob/issues/6)
|
||||
### Applicable scenes
|
||||
|
||||
ღ( ´・ᴗ・\` )ღ 感谢以下接入用户的大力支持 ღ( ´・ᴗ・\` )ღ
|
||||
- Timed tasks, for example, allocating e-coupons on 9 AM every morning.
|
||||
- Broadcast tasks, for example, broadcasting to the cluster to clear logs.
|
||||
- MapReduce tasks, for example, speeding up certain job like updating large amounts of data.
|
||||
- Delayed tasks, for example, processing overdue orders.
|
||||
- Customized tasks, triggered with [OpenAPI](https://www.yuque.com/powerjob/en/openapi).
|
||||
|
||||
<p align="center">
|
||||
### Online trial
|
||||
- Address: [try.powerjob.tech](http://try.powerjob.tech/#/welcome?appName=powerjob-agent-test&password=123)
|
||||
- Recommend reading the documentation first: [here](https://www.yuque.com/powerjob/en/trial)
|
||||
|
||||
# Documents
|
||||
**[Docs](https://www.yuque.com/powerjob/en/introduce)**
|
||||
|
||||
**[中文文档](https://www.yuque.com/powerjob/guidence/intro)**
|
||||
|
||||
# Known Users
|
||||
[Click to register as PowerJob user!](https://github.com/PowerJob/PowerJob/issues/6)
|
||||
ღ( ´・ᴗ・\` )ღ Many thanks to the following registered users. ღ( ´・ᴗ・\` )ღ
|
||||
<p style="text-align: center">
|
||||
<img src="https://raw.githubusercontent.com/KFCFans/PowerJob/master/others/images/user.png" alt="PowerJob User" title="PowerJob User"/>
|
||||
</p>
|
||||
|
||||
# 其他
|
||||
* 开源许可证:Apache License, Version 2.0
|
||||
* 欢迎共同参与本项目的贡献,PR和Issue都大大滴欢迎(求求了)~
|
||||
* 觉得还不错的话,可以点个Star支持一下哦~ = ̄ω ̄=
|
||||
* 联系方式@KFCFans -> `tengjiqi@gmail.com`
|
||||
* 用户交流QQ群:487453839
|
||||
# Stargazers over time
|
||||
|
||||
[](https://starchart.cc/PowerJob/PowerJob)
|
||||
|
||||
# License
|
||||
|
||||
PowerJob is released under Apache License 2.0. Please refer to [License](./LICENSE) for details.
|
||||
|
||||
# Others
|
||||
|
||||
- Any developer interested in getting more involved in PowerJob may join our [Reddit](https://www.reddit.com/r/PowerJob) or [Gitter](https://gitter.im/PowerJob/community) community and make [contributions](https://github.com/PowerJob/PowerJob/pulls)!
|
||||
|
||||
- Reach out to me through email **tengjiqi@gmail.com**. Any issues or questions are welcomed on [Issues](https://github.com/PowerJob/PowerJob/issues).
|
||||
|
||||
- Look forward to your opinions. Response may be late but not denied.
|
||||
|
@ -1,63 +0,0 @@
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/KFCFans/PowerJob/master/others/images/logo.png" alt="PowerJob" title="PowerJob" width="557"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/KFCFans/PowerJob/actions"><img src="https://github.com/KFCFans/PowerJob/workflows/Java%20CI%20with%20Maven/badge.svg?branch=master" alt="actions"></a>
|
||||
<a href="https://search.maven.org/search?q=com.github.kfcfans"><img alt="Maven Central" src="https://img.shields.io/maven-central/v/com.github.kfcfans/powerjob-worker"></a>
|
||||
<a href="https://github.com/KFCFans/PowerJob/releases"><img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/kfcfans/powerjob?color=%23E59866"></a>
|
||||
<a href="https://github.com/KFCFans/PowerJob/blob/master/LICENSE"><img src="https://img.shields.io/github/license/KFCFans/PowerJob" alt="LICENSE"></a>
|
||||
</p>
|
||||
|
||||
- Have you ever wondered how cron jobs could be organized orderly?
|
||||
- Have you ever felt upset when scheduling tasks suddenly terminated without any warning?
|
||||
- Have you ever felt helpless when batches of business tasks require handling?
|
||||
- Have you ever felt depressed about tasks that carry with complex dependencies?
|
||||
|
||||
Well, PowerJob is there for you, it is the choice of a new generation.It is a powerful, business-oriented scheduling framework that provides distributed computing ability.Based on Akka architecture, it makes everything with scheduling easier.Just with several steps, PowerJob could be deployed and work for you!
|
||||
|
||||
# Introduction
|
||||
|
||||
### Features
|
||||
- Simple to use: PowerJob provides a friendly front-end Web that allows developers to visually manage tasks (Create, Read, Update and Delete), monitor task status, and view operation logs online.
|
||||
- Complete timing strategy: PowerJob supports four different scheduling strategies, including CRON expression, fixed frequency timing, fixed delay timing as well as the Open API.
|
||||
- Various execution modes: PowerJob supports four execution modes: stand-alone, broadcast, Map, and MapReduce. It's worth mentioning the Map and MapReduce modes. With the completion of several lines of codes, developers could take full advantage of PowerJob's distributed computing ability.
|
||||
- Complete workflow support. PowerJob supports DAG(Directed acyclic graph) based online task configuration. Developers could arrange tasks on the console, while data could be transferred between tasks on the flow.
|
||||
- Extensive executor support: PowerJob supports multiple processors, including Spring Beans, ordinary Java objects, Shell, Python and so on.
|
||||
- Simple in dependency: PowerJob aims to be simple in dependency. The only dependency is merely database (MySQL / Oracle / MS SQLServer ...), with MongoDB being the extra dependency for storing huge online logs.
|
||||
- High availability and performance: Unlike traditional job-scheduling frameworks which rely on database locks, PowerJob server is lock-free when scheduling. PowerJob supports unlimited horizontal expansion. It's easy to achieve high availability and performance just by deploying as many PowerJob server instances as you need.
|
||||
- Quick failover and recovery support: Whenever any task failed, PowerJob server would retry according to the configured strategy. As long as there were enough nodes in the cluster, the failed tasks could execute successfully finally.
|
||||
- Convenient to run and maintain: PowerJob supports online logging. Logs generated by the worker would be transferred and displayed on the console instantly, therefore reducing the cost of debugging and improving the efficiency for developers significantly.
|
||||
|
||||
### Applicable scene
|
||||
|
||||
- Scenarios with timed tasks: such as full synchronization of data at midnight, generating business reports at desired time.
|
||||
- Scenarios that require all machines to run tasks simultaneously: such as log cleanup.
|
||||
- Scenarios that require distributed processing: For example, a large amount of data requires updating, while the stand-alone execution takes quite a lot of time. The Map/MapReduce mode could be applied while the workers would join the cluster for PowerJob server to dispatch, to speed up the time-consuming process, therefore improving the computing ablility of whole cluster.
|
||||
|
||||
### Comparison of similar products
|
||||
|
||||
| | QuartZ | xxl-job | SchedulerX 2.0 | PowerJob |
|
||||
| ---------------------------------- | --------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| Timing type | CRON | CRON | CRON, fixed frequency, fixed delay, OpenAPI | **CRON, fixed frequency, fixed delay, OpenAPI** |
|
||||
| Task type | Built-in Java | Built-in Java, GLUE Java, Shell, Python and other scripts | Built-in Java, external Java (FatJar), Shell, Python and other scripts | **Built-in Java, external Java (container), Shell, Python and other scripts** |
|
||||
| Distributed strategy | Unsupported | Static sharding | MapReduce dynamic sharding | **MapReduce dynamic sharding** |
|
||||
| Online task management | Unsupported | Supported | Supported | **Supported** |
|
||||
| Online logging | Unsupported | Supported | Unsupported | **Supported** |
|
||||
| Scheduling methods and performance | Based on database lock, there is a performance bottleneck | Based on database lock, there is a performance bottleneck | Unknown | **Lock-free design, powerful performance without upper limit** |
|
||||
| Alarm monitoring | Unsupported | Email | SMS | **Email, WebHook, Dingtalk. An interface is provided for customization.** |
|
||||
| System dependence | Any relational database (MySQL, Oracle ...) supported by JDBC | MySQL | RMB (free during public beta, hey, help to advertise) | **Any relational database (MySQL, Oracle ...) supported by Spring Data Jpa** |
|
||||
| workflow | Unsupported | Unsupported | Supported | **Supported** |
|
||||
|
||||
# Document
|
||||
**[GitHub Wiki](https://github.com/KFCFans/PowerJob/wiki)**
|
||||
|
||||
**[中文文档](https://www.yuque.com/powerjob/product)**
|
||||
|
||||
# Others
|
||||
|
||||
- PowerJob is permanently open source software(Apache License, Version 2.0), please feel free to try, use or deploy!
|
||||
- Owner of PowerJob (@KFCFans) has abundant time for maintenance, and is willing to provide technical support if you have needs!
|
||||
- Welcome to contribute to PowerJob, both Pull Requests and Issues are precious.
|
||||
- Please STAR PowerJob if it is valuable. ~ =  ̄ω ̄ =
|
||||
- Do you need any help or want to propose suggestions? Please raise Github issues or contact the Author @KFCFans-> `tengjiqi@gmail.com` directly.
|
78
README_zhCN.md
Normal file
78
README_zhCN.md
Normal file
@ -0,0 +1,78 @@
|
||||
# [English](./README.md) | 简体中文
|
||||
|
||||
<p align="center">
|
||||
🏮PowerJob 全体成员祝大家龙年腾飞,新的一年身体健康,万事如意,阖家欢乐,幸福安康!🏮
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/KFCFans/PowerJob/master/others/images/logo.png" alt="PowerJob" title="PowerJob" width="557"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/PowerJob/PowerJob/actions"><img src="https://github.com/PowerJob/PowerJob/workflows/Java%20CI%20with%20Maven/badge.svg?branch=master" alt="actions"></a>
|
||||
<a href="https://search.maven.org/search?q=tech.powerjob"><img alt="Maven Central" src="https://img.shields.io/maven-central/v/tech.powerjob/powerjob-worker"></a>
|
||||
<a href="https://github.com/PowerJob/PowerJob/releases"><img alt="GitHub release (latest SemVer)" src="https://img.shields.io/github/v/release/kfcfans/powerjob?color=%23E59866"></a>
|
||||
<a href="https://github.com/PowerJob/PowerJob/blob/master/LICENSE"><img src="https://img.shields.io/github/license/KFCFans/PowerJob" alt="LICENSE"></a>
|
||||
</p>
|
||||
|
||||
PowerJob(原OhMyScheduler)是全新一代分布式调度与计算框架,能让您轻松完成作业的调度与繁杂任务的分布式计算。
|
||||
# 简介
|
||||
### 主要特性
|
||||
* 使用简单:提供前端Web界面,允许开发者可视化地完成调度任务的管理(增、删、改、查)、任务运行状态监控和运行日志查看等功能。
|
||||
* 定时策略完善:支持CRON表达式、固定频率、固定延迟和API四种定时调度策略。
|
||||
* 执行模式丰富:支持单机、广播、Map、MapReduce四种执行模式,其中Map/MapReduce处理器能使开发者寥寥数行代码便获得集群分布式计算的能力。
|
||||
* DAG工作流支持:支持在线配置任务依赖关系,可视化得对任务进行编排,同时还支持上下游任务间的数据传递
|
||||
* 执行器支持广泛:支持Spring Bean、内置/外置Java类、Shell、Python等处理器,应用范围广。
|
||||
* 运维便捷:支持在线日志功能,执行器产生的日志可以在前端控制台页面实时显示,降低debug成本,极大地提高开发效率。
|
||||
* 依赖精简:最小仅依赖关系型数据库(MySQL/Oracle/MS SQLServer...)。
|
||||
* 高可用&高性能:调度服务器经过精心设计,一改其他调度框架基于数据库锁的策略,实现了无锁化调度。部署多个调度服务器可以同时实现高可用和性能的提升(支持无限的水平扩展)。
|
||||
* 故障转移与恢复:任务执行失败后,可根据配置的重试策略完成重试,只要执行器集群有足够的计算节点,任务就能顺利完成。
|
||||
|
||||
### 适用场景
|
||||
* 有定时执行需求的业务场景:如每天凌晨全量同步数据、生成业务报表等。
|
||||
* 有需要全部机器一同执行的业务场景:如使用广播执行模式清理集群日志。
|
||||
* 有需要分布式处理的业务场景:比如需要更新一大批数据,单机执行耗时非常长,可以使用Map/MapReduce处理器完成任务的分发,调动整个集群加速计算。
|
||||
* 有需要**延迟执行**某些任务的业务场景:比如订单过期处理等。
|
||||
|
||||
### 设计目标
|
||||
PowerJob 的设计目标为企业级的分布式任务调度平台,即成为公司内部的**任务调度中间件**。整个公司统一部署调度中心 powerjob-server,旗下所有业务线应用只需要依赖 `powerjob-worker` 即可接入调度中心获取任务调度与分布式计算能力。
|
||||
|
||||
### 在线试用
|
||||
* [点击查看试用说明和教程](https://www.yuque.com/powerjob/guidence/trial)
|
||||
|
||||
### 同类产品对比
|
||||
| | QuartZ | xxl-job | SchedulerX 2.0 | PowerJob |
|
||||
| -------------- | ------------------------ | ---------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------ |
|
||||
| 定时类型 | CRON | CRON | CRON、固定频率、固定延迟、OpenAPI | **CRON、固定频率、固定延迟、OpenAPI** |
|
||||
| 任务类型 | 内置Java | 内置Java、GLUE Java、Shell、Python等脚本 | 内置Java、外置Java(FatJar)、Shell、Python等脚本 | **内置Java、外置Java(容器)、Shell、Python等脚本** |
|
||||
| 分布式计算 | 无 | 静态分片 | MapReduce动态分片 | **MapReduce动态分片** |
|
||||
| 在线任务治理 | 不支持 | 支持 | 支持 | **支持** |
|
||||
| 日志白屏化 | 不支持 | 支持 | 不支持 | **支持** |
|
||||
| 调度方式及性能 | 基于数据库锁,有性能瓶颈 | 基于数据库锁,有性能瓶颈 | 不详 | **无锁化设计,性能强劲无上限** |
|
||||
| 报警监控 | 无 | 邮件 | 短信 | **WebHook、邮件、钉钉与自定义扩展** |
|
||||
| 系统依赖 | JDBC支持的关系型数据库(MySQL、Oracle...) | MySQL | 人民币 | **任意Spring Data Jpa支持的关系型数据库(MySQL、Oracle...)** |
|
||||
| DAG工作流 | 不支持 | 不支持 | 支持 | **支持** |
|
||||
|
||||
|
||||
# 官方文档
|
||||
**[中文文档](https://www.yuque.com/powerjob/guidence/intro)**
|
||||
|
||||
**[Docs](https://www.yuque.com/powerjob/en/introduce)**
|
||||
|
||||
# 接入登记
|
||||
[点击进行接入登记,为 PowerJob 的发展贡献自己的力量!](https://github.com/PowerJob/PowerJob/issues/6)
|
||||
|
||||
ღ( ´・ᴗ・\` )ღ 感谢以下接入用户的大力支持 ღ( ´・ᴗ・\` )ღ
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/KFCFans/PowerJob/master/others/images/user.png" alt="PowerJob User" title="PowerJob User"/>
|
||||
</p>
|
||||
|
||||
# 其他
|
||||
* 开源许可证:Apache License, Version 2.0
|
||||
* 欢迎共同参与本项目的贡献,PR和Issue都大大滴欢迎(求求了)~
|
||||
* 觉得还不错的话,可以点个Star支持一下哦~ = ̄ω ̄=
|
||||
* 联系方式@KFCFans -> `tengjiqi@gmail.com`
|
||||
* 用户交流QQ群(因广告信息泛滥,加群需要验证,请认真填写申请原因):
|
||||
* 一群(已满):487453839
|
||||
* 二群:834937813
|
4
SECURITY.md
Normal file
4
SECURITY.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Security notices relating to PowerJob
|
||||
|
||||
Please disclose any security issues or vulnerabilities found through [Tidelift's coordinated disclosure system](https://tidelift.com/security) or to the maintainers privately(tengjiqi@gmail.com).
|
||||
|
54
docker-compose.yml
Normal file
54
docker-compose.yml
Normal file
@ -0,0 +1,54 @@
|
||||
# 使用说明 V4.3.1
|
||||
# 1. PowerJob 根目录执行:docker-compose up
|
||||
# 2. 静静等待服务启动。
|
||||
|
||||
version: '3'
|
||||
services:
|
||||
powerjob-mysql:
|
||||
environment:
|
||||
MYSQL_ROOT_HOST: "%"
|
||||
MYSQL_ROOT_PASSWORD: No1Bug2Please3!
|
||||
restart: always
|
||||
container_name: powerjob-mysql
|
||||
image: powerjob/powerjob-mysql:latest
|
||||
ports:
|
||||
- "3307:3306"
|
||||
volumes:
|
||||
- ./powerjob-data/powerjob-mysql:/var/lib/mysql
|
||||
command: --lower_case_table_names=1
|
||||
|
||||
powerjob-server:
|
||||
container_name: powerjob-server
|
||||
image: powerjob/powerjob-server:latest
|
||||
restart: always
|
||||
depends_on:
|
||||
- powerjob-mysql
|
||||
environment:
|
||||
JVMOPTIONS: "-Xmx512m"
|
||||
PARAMS: "--oms.mongodb.enable=false --spring.datasource.core.jdbc-url=jdbc:mysql://powerjob-mysql:3306/powerjob-daily?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"
|
||||
ports:
|
||||
- "7700:7700"
|
||||
- "10086:10086"
|
||||
- "10010:10010"
|
||||
volumes:
|
||||
- ./powerjob-data/powerjob-server:/root/powerjob/server/
|
||||
|
||||
powerjob-worker-samples:
|
||||
container_name: powerjob-worker-samples
|
||||
image: powerjob/powerjob-worker-samples:latest
|
||||
restart: always
|
||||
depends_on:
|
||||
- powerjob-mysql
|
||||
- powerjob-server
|
||||
# environment:
|
||||
# PARAMS: "--powerjob.worker.server-address=powerjob-server:7700"
|
||||
ports:
|
||||
- "8081:8081"
|
||||
- "27777:27777"
|
||||
volumes:
|
||||
- ./powerjob-data/powerjob-worker-samples:/root/powerjob/worker
|
||||
- ./others/script/wait-for-it.sh:/wait-for-it.sh
|
||||
entrypoint:
|
||||
- "sh"
|
||||
- "-c"
|
||||
- "chmod +x wait-for-it.sh && ./wait-for-it.sh powerjob-server:7700 --strict -- java -Xmx512m -jar /powerjob-worker-samples.jar --powerjob.worker.server-address=powerjob-server:7700"
|
11
others/Dockerfile
Normal file
11
others/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM mysql/mysql-server:8.0.30
|
||||
|
||||
MAINTAINER dudiao(idudaio@163.com)
|
||||
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
COPY sql/01schema.sql /docker-entrypoint-initdb.d
|
||||
|
||||
COPY sql/02worker-samples.sql /docker-entrypoint-initdb.d
|
19
others/dev/build_test_env.sh
Executable file
19
others/dev/build_test_env.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# 构建 PowerJob 测试环境
|
||||
|
||||
echo "================== 关闭全部服务 =================="
|
||||
docker-compose down
|
||||
echo "================== 构建 jar =================="
|
||||
cd `dirname $0`/../.. || exit
|
||||
# mvn clean package -Pdev -DskipTests -U -e -pl powerjob-server,powerjob-worker-agent -am
|
||||
# -U:强制检查snapshot库 -pl:指定需要构建的模块,多模块逗号分割 -am:同时构建依赖模块,一般与pl连用 -Pxxx:指定使用的配置文件
|
||||
mvn clean package -Pdev -DskipTests
|
||||
echo "================== 拷贝 jar =================="
|
||||
/bin/cp -rf powerjob-server/powerjob-server-starter/target/*.jar powerjob-server/docker/powerjob-server.jar
|
||||
/bin/cp -rf powerjob-worker-agent/target/*.jar powerjob-worker-agent/powerjob-agent.jar
|
||||
ls -l powerjob-server/docker/powerjob-server.jar
|
||||
ls -l powerjob-worker-agent/powerjob-agent.jar
|
||||
|
||||
cd others/dev
|
||||
docker-compose build
|
||||
docker-compose --compatibility up
|
109
others/dev/docker-compose.yml
Normal file
109
others/dev/docker-compose.yml
Normal file
@ -0,0 +1,109 @@
|
||||
# 构建 PowerJob 测试环境
|
||||
|
||||
version: '3.7'
|
||||
services:
|
||||
powerjob-mysql:
|
||||
build:
|
||||
context: ../
|
||||
environment:
|
||||
MYSQL_ROOT_HOST: "%"
|
||||
MYSQL_ROOT_PASSWORD: No1Bug2Please3!
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 768M
|
||||
restart: always
|
||||
container_name: powerjob-mysql
|
||||
image: powerjob/powerjob-mysql:test_env
|
||||
ports:
|
||||
- "3309:3306"
|
||||
volumes:
|
||||
- ~/powerjob-data/powerjob-mysql:/var/lib/mysql
|
||||
command: --lower_case_table_names=1
|
||||
# powerjob-mongodb:
|
||||
# image: mongo:latest
|
||||
# container_name: powerjob-mongodb
|
||||
# restart: always
|
||||
# deploy:
|
||||
# resources:
|
||||
# limits:
|
||||
# memory: 256M
|
||||
# environment:
|
||||
# MONGO_INITDB_ROOT_USERNAME: "root"
|
||||
# MONGO_INITDB_ROOT_PASSWORD: "No1Bug2Please3!"
|
||||
# MONGO_INITDB_DATABASE: "powerjob_daily"
|
||||
# ports:
|
||||
# - "27017:27017"
|
||||
# volumes:
|
||||
# - ./testenv/init_mongodb.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
|
||||
# - ~/powerjob-data/powerjob-mongodb:/data/db
|
||||
powerjob-server:
|
||||
build:
|
||||
context: ../../powerjob-server/docker
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 896M
|
||||
container_name: powerjob-server
|
||||
image: powerjob/powerjob-server:test_env
|
||||
restart: always
|
||||
depends_on:
|
||||
- powerjob-mysql
|
||||
# - powerjob-mongodb
|
||||
environment:
|
||||
PARAMS: "--spring.profiles.active=daily --spring.datasource.core.jdbc-url=jdbc:mysql://powerjob-mysql:3306/powerjob-daily?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai --oms.storage.dfs.mysql_series.url=jdbc:mysql://powerjob-mysql:3306/powerjob-daily?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"
|
||||
JVMOPTIONS: "-server -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=7 -XX:GCLogFileSize=100M -Xloggc:/root/powerjob/server/gc.log"
|
||||
ports:
|
||||
- "7700:7700"
|
||||
- "10086:10086"
|
||||
- "10010:10010"
|
||||
volumes:
|
||||
- ~/powerjob-data/powerjob-server:/root/powerjob/server/
|
||||
- ~/.m2:/root/.m2
|
||||
|
||||
powerjob-worker-agent:
|
||||
build:
|
||||
context: ../../powerjob-worker-agent
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 384M
|
||||
container_name: powerjob-worker-agent
|
||||
image: powerjob/powerjob-worker-agent:test_env
|
||||
restart: always
|
||||
depends_on:
|
||||
- powerjob-mysql
|
||||
- powerjob-server
|
||||
ports:
|
||||
- "5002:5005"
|
||||
- "10002:10000"
|
||||
- "27777:27777"
|
||||
volumes:
|
||||
- ~/powerjob-data/powerjob-worker-agent:/root
|
||||
entrypoint:
|
||||
- "sh"
|
||||
- "-c"
|
||||
- "./wait-for-it.sh powerjob-server:7700 --strict -- java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10000 -Dcom.sun.management.jmxremote.rmi.port=10000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -server -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=7 -XX:GCLogFileSize=100M -Xloggc:/root/gc.log -jar /powerjob-agent.jar --app powerjob-worker-samples --server powerjob-server:7700"
|
||||
|
||||
powerjob-worker-agent2:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 384M
|
||||
container_name: powerjob-worker-agent2
|
||||
image: powerjob/powerjob-worker-agent:test_env
|
||||
restart: always
|
||||
depends_on:
|
||||
- powerjob-mysql
|
||||
- powerjob-server
|
||||
ports:
|
||||
- "5003:5005"
|
||||
- "10003:10000"
|
||||
- "27778:27777"
|
||||
volumes:
|
||||
- ~/powerjob-data/powerjob-worker-agent2:/root
|
||||
entrypoint:
|
||||
- "sh"
|
||||
- "-c"
|
||||
- "./wait-for-it.sh powerjob-server:7700 --strict -- java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10000 -Dcom.sun.management.jmxremote.rmi.port=10000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -server -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=7 -XX:GCLogFileSize=100M -Xloggc:/root/gc.log -jar /powerjob-agent.jar --app powerjob-worker-samples --server powerjob-server:7700"
|
||||
|
@ -11,10 +11,11 @@ cd `dirname $0`/../.. || exit
|
||||
read -r -p "是否进行maven构建(y/n):" needmvn
|
||||
if [ "$needmvn" = "y" ] || [ "$needmvn" = "Y" ]; then
|
||||
echo "================== 构建 jar =================="
|
||||
# mvn clean package -Pdev -DskipTests -U -e -pl powerjob-server,powerjob-worker-agent -am
|
||||
# -U:强制检查snapshot库 -pl:指定需要构建的模块,多模块逗号分割 -am:同时构建依赖模块,一般与pl连用 -Pxxx:指定使用的配置文件
|
||||
mvn clean package -Pdev -DskipTests -U -e -pl powerjob-server,powerjob-worker-agent -am
|
||||
mvn clean package -Pdev -DskipTests -U -e
|
||||
echo "================== 拷贝 jar =================="
|
||||
/bin/cp -rf powerjob-server/target/*.jar powerjob-server/docker/powerjob-server.jar
|
||||
/bin/cp -rf powerjob-server/powerjob-server-starter/target/*.jar powerjob-server/docker/powerjob-server.jar
|
||||
/bin/cp -rf powerjob-worker-agent/target/*.jar powerjob-worker-agent/powerjob-agent.jar
|
||||
ls -l powerjob-server/docker/powerjob-server.jar
|
||||
ls -l powerjob-worker-agent/powerjob-agent.jar
|
||||
@ -32,11 +33,19 @@ read -r -p "是否重新构建镜像(y/n):" rebuild
|
||||
if [ "$rebuild" = "y" ] || [ "$rebuild" = "Y" ]; then
|
||||
echo "================== 删除旧镜像 =================="
|
||||
docker rmi -f tjqq/powerjob-server:$version
|
||||
docker rmi -f powerjob/powerjob-server:$version
|
||||
docker rmi -f tjqq/powerjob-agent:$version
|
||||
docker rmi -f powerjob/powerjob-agent:$version
|
||||
docker rmi -f powerjob/powerjob-mysql:$version
|
||||
docker rmi -f powerjob/powerjob-worker-samples:$version
|
||||
echo "================== 构建 powerjob-server 镜像 =================="
|
||||
docker build -t tjqq/powerjob-server:$version powerjob-server/docker/. || exit
|
||||
echo "================== 构建 powerjob-agent 镜像 =================="
|
||||
docker build -t tjqq/powerjob-agent:$version powerjob-worker-agent/. || exit
|
||||
echo "================== 构建 powerjob-mysql 镜像 =================="
|
||||
docker build -t powerjob/powerjob-mysql:$version others/. || exit
|
||||
echo "================== 构建 powerjob-worker-samples 镜像 =================="
|
||||
docker build -t powerjob/powerjob-worker-samples:$version powerjob-worker-samples/. || exit
|
||||
|
||||
read -r -p "是否正式发布该镜像(y/n):" needrelease
|
||||
if [ "$needrelease" = "y" ] || [ "$needrelease" = "Y" ]; then
|
||||
@ -46,6 +55,25 @@ if [ "$rebuild" = "y" ] || [ "$rebuild" = "Y" ]; then
|
||||
docker push tjqq/powerjob-server:$version
|
||||
echo "================== 正在推送 agent 镜像到中央仓库 =================="
|
||||
docker push tjqq/powerjob-agent:$version
|
||||
echo "================== 正在推送 powerjob-mysql 镜像到中央仓库 =================="
|
||||
docker push powerjob/powerjob-mysql:$version
|
||||
echo "================== 正在推送 samples 镜像到中央仓库 =================="
|
||||
docker push powerjob/powerjob-worker-samples:$version
|
||||
echo "================== 双写推送 =================="
|
||||
docker tag tjqq/powerjob-server:$version powerjob/powerjob-server:$version
|
||||
docker push powerjob/powerjob-server:$version
|
||||
docker tag tjqq/powerjob-agent:$version powerjob/powerjob-agent:$version
|
||||
docker push powerjob/powerjob-agent:$version
|
||||
echo "================== 更新 LATEST 版本 =================="
|
||||
docker tag powerjob/powerjob-server:$version powerjob/powerjob-server:latest
|
||||
docker push powerjob/powerjob-server:latest
|
||||
docker tag powerjob/powerjob-agent:$version powerjob/powerjob-agent:latest
|
||||
docker push powerjob/powerjob-agent:latest
|
||||
docker tag powerjob/powerjob-mysql:$version powerjob/powerjob-mysql:latest
|
||||
docker push powerjob/powerjob-mysql:latest
|
||||
docker tag powerjob/powerjob-worker-samples:$version powerjob/powerjob-worker-samples:latest
|
||||
docker push powerjob/powerjob-worker-samples:latest
|
||||
echo "================== Docker 推送完毕 =================="
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -62,7 +90,7 @@ if [ "$startup" = "y" ] || [ "$startup" = "Y" ]; then
|
||||
echo "================== 准备启动 powerjob-server =================="
|
||||
docker run -d \
|
||||
--name powerjob-server \
|
||||
-p 7700:7700 -p 10086:10086 -p 5001:5005 -p 10001:10000 \
|
||||
-p 7700:7700 -p 10086:10086 -p 10010:10010 -p 5001:5005 -p 10001:10000 \
|
||||
-e JVMOPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10000 -Dcom.sun.management.jmxremote.rmi.port=10000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" \
|
||||
-e PARAMS="--spring.profiles.active=pre" \
|
||||
-e TZ="Asia/Shanghai" \
|
71
others/dev/publish_docker_apple_silicon.sh
Executable file
71
others/dev/publish_docker_apple_silicon.sh
Executable file
@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
echo "A docker image release script for the Apple Silicon device."
|
||||
# -p:允许后面跟一个字符串作为提示 -r:保证读入的是原始内容,不会发生任何转义
|
||||
read -r -p "请输入Dockedr镜像版本:" version
|
||||
echo "即将构建的 server 镜像:powerjob-server:$version"
|
||||
echo "即将构建的 agent 镜像:powerjob-agent:$version"
|
||||
read -r -p "任意键继续:"
|
||||
|
||||
# 一键部署脚本,请勿挪动脚本
|
||||
cd `dirname $0`/../.. || exit
|
||||
|
||||
read -r -p "是否进行maven构建(y/n):" needmvn
|
||||
if [ "$needmvn" = "y" ] || [ "$needmvn" = "Y" ]; then
|
||||
echo "================== 构建 jar =================="
|
||||
# mvn clean package -Pdev -DskipTests -U -e -pl powerjob-server,powerjob-worker-agent -am
|
||||
# -U:强制检查snapshot库 -pl:指定需要构建的模块,多模块逗号分割 -am:同时构建依赖模块,一般与pl连用 -Pxxx:指定使用的配置文件
|
||||
mvn clean package -Pdev -DskipTests -U -e
|
||||
echo "================== 拷贝 jar =================="
|
||||
/bin/cp -rf powerjob-server/powerjob-server-starter/target/*.jar powerjob-server/docker/powerjob-server.jar
|
||||
/bin/cp -rf powerjob-worker-agent/target/*.jar powerjob-worker-agent/powerjob-agent.jar
|
||||
ls -l powerjob-server/docker/powerjob-server.jar
|
||||
ls -l powerjob-worker-agent/powerjob-agent.jar
|
||||
fi
|
||||
|
||||
echo "================== 关闭老应用 =================="
|
||||
docker stop powerjob-server
|
||||
docker stop powerjob-agent
|
||||
docker stop powerjob-agent2
|
||||
echo "================== 删除老容器 =================="
|
||||
docker container rm powerjob-server
|
||||
docker container rm powerjob-agent
|
||||
docker container rm powerjob-agent2
|
||||
read -r -p "是否构建并发布镜像(y/n):" rebuild
|
||||
if [ "$rebuild" = "y" ] || [ "$rebuild" = "Y" ]; then
|
||||
echo "================== 删除旧镜像 =================="
|
||||
docker rmi -f tjqq/powerjob-server:$version
|
||||
docker rmi -f powerjob/powerjob-server:$version
|
||||
docker rmi -f tjqq/powerjob-agent:$version
|
||||
docker rmi -f powerjob/powerjob-agent:$version
|
||||
docker rmi -f powerjob/powerjob-mysql:$version
|
||||
docker rmi -f powerjob/powerjob-worker-samples:$version
|
||||
echo "================== 构建 powerjob-server 镜像(tjqq) =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag tjqq/powerjob-server:$version powerjob-server/docker/. --push || exit
|
||||
echo "================== 构建 powerjob-server 镜像(powerjob) =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag powerjob/powerjob-server:$version powerjob-server/docker/. --push || exit
|
||||
echo "================== 构建 powerjob-agent 镜像(tjqq) =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag tjqq/powerjob-agent:$version powerjob-worker-agent/. --push|| exit
|
||||
echo "================== 构建 powerjob-agent 镜像(powerjob) =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag powerjob/powerjob-agent:$version powerjob-worker-agent/. --push|| exit
|
||||
echo "================== 构建 powerjob-mysql 镜像 =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag powerjob/powerjob-mysql:$version others/. --push|| exit
|
||||
echo "================== 构建 powerjob-worker-samples 镜像 =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag powerjob/powerjob-worker-samples:$version powerjob-worker-samples/. --push|| exit
|
||||
fi
|
||||
|
||||
read -r -p "是否推送LATEST(y/n):" push_latest
|
||||
if [ "$push_latest" = "y" ] || [ "$push_latest" = "Y" ]; then
|
||||
|
||||
echo "================== powerjob-server LATEST (tjqq) =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag tjqq/powerjob-server:latest powerjob-server/docker/. --push || exit
|
||||
echo "================== powerjob-server LATEST (powerjob) =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag powerjob/powerjob-server:latest powerjob-server/docker/. --push || exit
|
||||
echo "================== powerjob-agent LATEST (tjqq) =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag tjqq/powerjob-agent:latest powerjob-worker-agent/. --push|| exit
|
||||
echo "================== powerjob-agent LATEST (powerjob) =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag powerjob/powerjob-agent:latest powerjob-worker-agent/. --push|| exit
|
||||
echo "================== powerjob-mysql LATEST =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag powerjob/powerjob-mysql:latest others/. --push|| exit
|
||||
echo "================== powerjob-worker-samples LATEST =================="
|
||||
docker buildx build --platform=linux/amd64,linux/arm64 --tag powerjob/powerjob-worker-samples:latest powerjob-worker-samples/. --push|| exit
|
||||
fi
|
12
others/dev/testenv/init_mongodb.js
Normal file
12
others/dev/testenv/init_mongodb.js
Normal file
@ -0,0 +1,12 @@
|
||||
db.createUser(
|
||||
{
|
||||
user: "zqq",
|
||||
pwd: "No1Bug2Please3!",
|
||||
roles: [
|
||||
{
|
||||
role: "readWrite",
|
||||
db: "powerjob_daily"
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
Binary file not shown.
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 209 KiB |
328
others/powerjob-mysql.sql
Normal file
328
others/powerjob-mysql.sql
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
官方 SQL 仅基于特定版本(MySQL8)导出,不一定兼容其他数据库,也不一定兼容其他版本。此 SQL 仅供参考。
|
||||
如果您的数据库无法使用此 SQL,建议使用 SpringDataJPA 自带的建表能力,先在开发环境直连测试库自动建表,然后自行导出相关的 SQL 即可。
|
||||
*/
|
||||
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : Local@3306
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80300 (8.3.0)
|
||||
Source Host : localhost:3306
|
||||
Source Schema : powerjob5
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80300 (8.3.0)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 11/08/2024 23:23:30
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for app_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `app_info`;
|
||||
CREATE TABLE `app_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_name` varchar(255) DEFAULT NULL,
|
||||
`creator` bigint DEFAULT NULL,
|
||||
`current_server` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`modifier` bigint DEFAULT NULL,
|
||||
`namespace_id` bigint DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`tags` varchar(255) DEFAULT NULL,
|
||||
`title` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_app_info` (`app_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for container_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `container_info`;
|
||||
CREATE TABLE `container_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`container_name` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`last_deploy_time` datetime(6) DEFAULT NULL,
|
||||
`source_info` varchar(255) DEFAULT NULL,
|
||||
`source_type` int DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`version` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_container_info` (`app_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for instance_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `instance_info`;
|
||||
CREATE TABLE `instance_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`actual_trigger_time` bigint DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`expected_trigger_time` bigint DEFAULT NULL,
|
||||
`finished_time` bigint DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`instance_id` bigint DEFAULT NULL,
|
||||
`instance_params` longtext,
|
||||
`job_id` bigint DEFAULT NULL,
|
||||
`job_params` longtext,
|
||||
`last_report_time` bigint DEFAULT NULL,
|
||||
`result` longtext,
|
||||
`running_times` bigint DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`task_tracker_address` varchar(255) DEFAULT NULL,
|
||||
`type` int DEFAULT NULL,
|
||||
`wf_instance_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_instance_info` (`job_id`,`status`),
|
||||
KEY `idx02_instance_info` (`app_id`,`status`),
|
||||
KEY `idx03_instance_info` (`instance_id`,`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for job_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `job_info`;
|
||||
CREATE TABLE `job_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`advanced_runtime_config` varchar(255) DEFAULT NULL,
|
||||
`alarm_config` varchar(255) DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`concurrency` int DEFAULT NULL,
|
||||
`designated_workers` varchar(255) DEFAULT NULL,
|
||||
`dispatch_strategy` int DEFAULT NULL,
|
||||
`dispatch_strategy_config` varchar(255) DEFAULT NULL,
|
||||
`execute_type` int DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`instance_retry_num` int DEFAULT NULL,
|
||||
`instance_time_limit` bigint DEFAULT NULL,
|
||||
`job_description` varchar(255) DEFAULT NULL,
|
||||
`job_name` varchar(255) DEFAULT NULL,
|
||||
`job_params` longtext,
|
||||
`lifecycle` varchar(255) DEFAULT NULL,
|
||||
`log_config` varchar(255) DEFAULT NULL,
|
||||
`max_instance_num` int DEFAULT NULL,
|
||||
`max_worker_count` int DEFAULT NULL,
|
||||
`min_cpu_cores` double NOT NULL,
|
||||
`min_disk_space` double NOT NULL,
|
||||
`min_memory_space` double NOT NULL,
|
||||
`next_trigger_time` bigint DEFAULT NULL,
|
||||
`notify_user_ids` varchar(255) DEFAULT NULL,
|
||||
`processor_info` varchar(255) DEFAULT NULL,
|
||||
`processor_type` int DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`tag` varchar(255) DEFAULT NULL,
|
||||
`task_retry_num` int DEFAULT NULL,
|
||||
`time_expression` varchar(255) DEFAULT NULL,
|
||||
`time_expression_type` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_job_info` (`app_id`,`status`,`time_expression_type`,`next_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for namespace
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `namespace`;
|
||||
CREATE TABLE `namespace` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`code` varchar(255) DEFAULT NULL,
|
||||
`creator` bigint DEFAULT NULL,
|
||||
`dept` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`modifier` bigint DEFAULT NULL,
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`tags` varchar(255) DEFAULT NULL,
|
||||
`token` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_namespace` (`code`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for oms_lock
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `oms_lock`;
|
||||
CREATE TABLE `oms_lock` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`lock_name` varchar(255) DEFAULT NULL,
|
||||
`max_lock_time` bigint DEFAULT NULL,
|
||||
`ownerip` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_oms_lock` (`lock_name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for pwjb_user_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `pwjb_user_info`;
|
||||
CREATE TABLE `pwjb_user_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`username` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_username` (`username`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for server_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `server_info`;
|
||||
CREATE TABLE `server_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`ip` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_server_info` (`ip`),
|
||||
KEY `idx01_server_info` (`gmt_modified`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sundry
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sundry`;
|
||||
CREATE TABLE `sundry` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`content` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`pkey` varchar(255) DEFAULT NULL,
|
||||
`skey` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_sundry` (`pkey`,`skey`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_info`;
|
||||
CREATE TABLE `user_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`account_type` varchar(255) DEFAULT NULL,
|
||||
`email` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`nick` varchar(255) DEFAULT NULL,
|
||||
`origin_username` varchar(255) DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`phone` varchar(255) DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`token_login_verify_info` varchar(255) DEFAULT NULL,
|
||||
`username` varchar(255) DEFAULT NULL,
|
||||
`web_hook` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_user_name` (`username`),
|
||||
KEY `uidx02_user_info` (`email`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_role
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_role`;
|
||||
CREATE TABLE `user_role` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`role` int DEFAULT NULL,
|
||||
`scope` int DEFAULT NULL,
|
||||
`target` bigint DEFAULT NULL,
|
||||
`user_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `uidx01_user_id` (`user_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_info`;
|
||||
CREATE TABLE `workflow_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`lifecycle` varchar(255) DEFAULT NULL,
|
||||
`max_wf_instance_num` int DEFAULT NULL,
|
||||
`next_trigger_time` bigint DEFAULT NULL,
|
||||
`notify_user_ids` varchar(255) DEFAULT NULL,
|
||||
`pedag` longtext,
|
||||
`status` int DEFAULT NULL,
|
||||
`time_expression` varchar(255) DEFAULT NULL,
|
||||
`time_expression_type` int DEFAULT NULL,
|
||||
`wf_description` varchar(255) DEFAULT NULL,
|
||||
`wf_name` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_workflow_info` (`app_id`,`status`,`time_expression_type`,`next_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_instance_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_instance_info`;
|
||||
CREATE TABLE `workflow_instance_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`actual_trigger_time` bigint DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`dag` longtext,
|
||||
`expected_trigger_time` bigint DEFAULT NULL,
|
||||
`finished_time` bigint DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`parent_wf_instance_id` bigint DEFAULT NULL,
|
||||
`result` longtext,
|
||||
`status` int DEFAULT NULL,
|
||||
`wf_context` longtext,
|
||||
`wf_init_params` longtext,
|
||||
`wf_instance_id` bigint DEFAULT NULL,
|
||||
`workflow_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_wf_instance` (`wf_instance_id`),
|
||||
KEY `idx01_wf_instance` (`workflow_id`,`status`,`app_id`,`expected_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_node_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_node_info`;
|
||||
CREATE TABLE `workflow_node_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint NOT NULL,
|
||||
`enable` bit(1) NOT NULL,
|
||||
`extra` longtext,
|
||||
`gmt_create` datetime(6) NOT NULL,
|
||||
`gmt_modified` datetime(6) NOT NULL,
|
||||
`job_id` bigint DEFAULT NULL,
|
||||
`node_name` varchar(255) DEFAULT NULL,
|
||||
`node_params` longtext,
|
||||
`skip_when_failed` bit(1) NOT NULL,
|
||||
`type` int DEFAULT NULL,
|
||||
`workflow_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_workflow_node_info` (`workflow_id`,`gmt_create`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
@ -1,33 +1,32 @@
|
||||
#!/bin/bash
|
||||
cd `dirname $0`/../.. || exit
|
||||
echo "================== 构建 jar =================="
|
||||
mvn clean package -Pdev -DskipTests -U -e -pl powerjob-server,powerjob-worker-agent -am
|
||||
mvn clean package -Pdev -DskipTests -e
|
||||
echo "================== 拷贝 jar =================="
|
||||
/bin/cp -rf powerjob-server/target/*.jar powerjob-server/docker/powerjob-server.jar
|
||||
/bin/cp -rf powerjob-worker-agent/target/*.jar powerjob-worker-agent/powerjob-agent.jar
|
||||
/bin/cp -rf powerjob-server/powerjob-server-starter/target/*.jar powerjob-server/docker/powerjob-server.jar
|
||||
echo "================== 关闭老应用 =================="
|
||||
docker stop powerjob-server
|
||||
docker stop powerjob-agent
|
||||
docker stop powerjob-agent2
|
||||
docker stop powerjob-worker-samples
|
||||
docker stop powerjob-worker-samples2
|
||||
echo "================== 删除老容器 =================="
|
||||
docker container rm powerjob-server
|
||||
docker container rm powerjob-agent
|
||||
docker container rm powerjob-agent2
|
||||
docker container rm powerjob-worker-samples
|
||||
docker container rm powerjob-worker-samples2
|
||||
echo "================== 删除旧镜像 =================="
|
||||
docker rmi -f tjqq/powerjob-server:latest
|
||||
docker rmi -f tjqq/powerjob-agent:latest
|
||||
docker rmi -f tjqq/powerjob-worker-samples:latest
|
||||
echo "================== 构建 powerjob-server 镜像 =================="
|
||||
docker build -t tjqq/powerjob-server:latest powerjob-server/docker/. || exit
|
||||
echo "================== 构建 powerjob-agent 镜像 =================="
|
||||
docker build -t tjqq/powerjob-agent:latest powerjob-worker-agent/. || exit
|
||||
echo "================== 构建 powerjob-worker-samples 镜像 =================="
|
||||
docker build -t tjqq/powerjob-worker-samples:latest powerjob-worker-samples/. || exit
|
||||
echo "================== 准备启动 powerjob-server =================="
|
||||
docker run -d \
|
||||
--restart=always \
|
||||
--name powerjob-server \
|
||||
-p 7700:7700 -p 10086:10086 -p 5001:5005 -p 10001:10000 \
|
||||
-e JVMOPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10000 -Dcom.sun.management.jmxremote.rmi.port=10000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" \
|
||||
-e PARAMS="--spring.profiles.active=product --spring.datasource.core.jdbc-url=jdbc:mysql://remotehost:3306/powerjob-product?useUnicode=true&characterEncoding=UTF-8 --spring.data.mongodb.uri=mongodb://remotehost:27017/powerjob-product" \
|
||||
-v ~/docker/powerjob-server:/root/powerjob-server -v ~/.m2:/root/.m2 \
|
||||
-e PARAMS="--oms.swagger.enable=true --spring.profiles.active=product --spring.datasource.core.jdbc-url=jdbc:mysql://remotehost:3306/powerjob-product?useUnicode=true&characterEncoding=UTF-8 --oms.mongodb.enable=false --spring.data.mongodb.uri=mongodb://remotehost:27017/powerjob-product" \
|
||||
-v ~/docker/powerjob-server:/root/powerjob/server -v ~/.m2:/root/.m2 \
|
||||
tjqq/powerjob-server:latest
|
||||
sleep 60
|
||||
echo "================== 准备启动 powerjob-agent =================="
|
||||
@ -37,19 +36,19 @@ echo "使用的Server地址:$serverAddress"
|
||||
|
||||
docker run -d \
|
||||
--restart=always \
|
||||
--name powerjob-agent \
|
||||
--name powerjob-worker-samples \
|
||||
-p 27777:27777 -p 5002:5005 -p 10002:10000 \
|
||||
-e JVMOPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10000 -Dcom.sun.management.jmxremote.rmi.port=10000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" \
|
||||
-e PARAMS="--app powerjob-agent-test --server $serverAddress" \
|
||||
-v ~/docker/powerjob-agent:/root \
|
||||
tjqq/powerjob-agent:latest
|
||||
-e PARAMS="--powerjob.worker.server-address=$serverAddress" \
|
||||
-v ~/docker/powerjob-worker-samples:/root \
|
||||
tjqq/powerjob-worker-samples:latest
|
||||
|
||||
docker run -d \
|
||||
--restart=always \
|
||||
--name powerjob-agent2 \
|
||||
--name powerjob-worker-samples2 \
|
||||
-p 27778:27777 -p 5003:5005 -p 10003:10000 \
|
||||
-e JVMOPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=10000 -Dcom.sun.management.jmxremote.rmi.port=10000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" \
|
||||
-e PARAMS="--app powerjob-agent-test --server $serverAddress" \
|
||||
-v ~/docker/powerjob-agent2:/root \
|
||||
tjqq/powerjob-agent:latest
|
||||
-e PARAMS="--powerjob.worker.server-address=$serverAddress" \
|
||||
-v ~/docker/powerjob-worker-samples2:/root \
|
||||
tjqq/powerjob-worker-samples:latest
|
||||
|
||||
|
182
others/script/wait-for-it.sh
Executable file
182
others/script/wait-for-it.sh
Executable file
@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env bash
|
||||
# Use this script to test if a given TCP host/port are available
|
||||
|
||||
WAITFORIT_cmdname=${0##*/}
|
||||
|
||||
echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
|
||||
|
||||
usage()
|
||||
{
|
||||
cat << USAGE >&2
|
||||
Usage:
|
||||
$WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
|
||||
-h HOST | --host=HOST Host or IP under test
|
||||
-p PORT | --port=PORT TCP port under test
|
||||
Alternatively, you specify the host and port as host:port
|
||||
-s | --strict Only execute subcommand if the test succeeds
|
||||
-q | --quiet Don't output any status messages
|
||||
-t TIMEOUT | --timeout=TIMEOUT
|
||||
Timeout in seconds, zero for no timeout
|
||||
-- COMMAND ARGS Execute command with args after the test finishes
|
||||
USAGE
|
||||
exit 1
|
||||
}
|
||||
|
||||
wait_for()
|
||||
{
|
||||
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
||||
echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
||||
else
|
||||
echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
|
||||
fi
|
||||
WAITFORIT_start_ts=$(date +%s)
|
||||
while :
|
||||
do
|
||||
if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
|
||||
nc -z $WAITFORIT_HOST $WAITFORIT_PORT
|
||||
WAITFORIT_result=$?
|
||||
else
|
||||
(echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
|
||||
WAITFORIT_result=$?
|
||||
fi
|
||||
if [[ $WAITFORIT_result -eq 0 ]]; then
|
||||
WAITFORIT_end_ts=$(date +%s)
|
||||
echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return $WAITFORIT_result
|
||||
}
|
||||
|
||||
wait_for_wrapper()
|
||||
{
|
||||
# In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
|
||||
if [[ $WAITFORIT_QUIET -eq 1 ]]; then
|
||||
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
||||
else
|
||||
timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
|
||||
fi
|
||||
WAITFORIT_PID=$!
|
||||
trap "kill -INT -$WAITFORIT_PID" INT
|
||||
wait $WAITFORIT_PID
|
||||
WAITFORIT_RESULT=$?
|
||||
if [[ $WAITFORIT_RESULT -ne 0 ]]; then
|
||||
echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
|
||||
fi
|
||||
return $WAITFORIT_RESULT
|
||||
}
|
||||
|
||||
# process arguments
|
||||
while [[ $# -gt 0 ]]
|
||||
do
|
||||
case "$1" in
|
||||
*:* )
|
||||
WAITFORIT_hostport=(${1//:/ })
|
||||
WAITFORIT_HOST=${WAITFORIT_hostport[0]}
|
||||
WAITFORIT_PORT=${WAITFORIT_hostport[1]}
|
||||
shift 1
|
||||
;;
|
||||
--child)
|
||||
WAITFORIT_CHILD=1
|
||||
shift 1
|
||||
;;
|
||||
-q | --quiet)
|
||||
WAITFORIT_QUIET=1
|
||||
shift 1
|
||||
;;
|
||||
-s | --strict)
|
||||
WAITFORIT_STRICT=1
|
||||
shift 1
|
||||
;;
|
||||
-h)
|
||||
WAITFORIT_HOST="$2"
|
||||
if [[ $WAITFORIT_HOST == "" ]]; then break; fi
|
||||
shift 2
|
||||
;;
|
||||
--host=*)
|
||||
WAITFORIT_HOST="${1#*=}"
|
||||
shift 1
|
||||
;;
|
||||
-p)
|
||||
WAITFORIT_PORT="$2"
|
||||
if [[ $WAITFORIT_PORT == "" ]]; then break; fi
|
||||
shift 2
|
||||
;;
|
||||
--port=*)
|
||||
WAITFORIT_PORT="${1#*=}"
|
||||
shift 1
|
||||
;;
|
||||
-t)
|
||||
WAITFORIT_TIMEOUT="$2"
|
||||
if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
|
||||
shift 2
|
||||
;;
|
||||
--timeout=*)
|
||||
WAITFORIT_TIMEOUT="${1#*=}"
|
||||
shift 1
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
WAITFORIT_CLI=("$@")
|
||||
break
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echoerr "Unknown argument: $1"
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
|
||||
echoerr "Error: you need to provide a host and port to test."
|
||||
usage
|
||||
fi
|
||||
|
||||
WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
|
||||
WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
|
||||
WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
|
||||
WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
|
||||
|
||||
# Check to see if timeout is from busybox?
|
||||
WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
|
||||
WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
|
||||
|
||||
WAITFORIT_BUSYTIMEFLAG=""
|
||||
if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
|
||||
WAITFORIT_ISBUSY=1
|
||||
# Check if busybox timeout uses -t flag
|
||||
# (recent Alpine versions don't support -t anymore)
|
||||
if timeout &>/dev/stdout | grep -q -e '-t '; then
|
||||
WAITFORIT_BUSYTIMEFLAG="-t"
|
||||
fi
|
||||
else
|
||||
WAITFORIT_ISBUSY=0
|
||||
fi
|
||||
|
||||
if [[ $WAITFORIT_CHILD -gt 0 ]]; then
|
||||
wait_for
|
||||
WAITFORIT_RESULT=$?
|
||||
exit $WAITFORIT_RESULT
|
||||
else
|
||||
if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
|
||||
wait_for_wrapper
|
||||
WAITFORIT_RESULT=$?
|
||||
else
|
||||
wait_for
|
||||
WAITFORIT_RESULT=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $WAITFORIT_CLI != "" ]]; then
|
||||
if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
|
||||
echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
|
||||
exit $WAITFORIT_RESULT
|
||||
fi
|
||||
exec "${WAITFORIT_CLI[@]}"
|
||||
else
|
||||
exit $WAITFORIT_RESULT
|
||||
fi
|
2
others/sql/01schema.sql
Normal file
2
others/sql/01schema.sql
Normal file
@ -0,0 +1,2 @@
|
||||
-- powerjob
|
||||
create database `powerjob-daily` default character set utf8mb4 collate utf8mb4_general_ci;
|
21
others/sql/02worker-samples.sql
Normal file
21
others/sql/02worker-samples.sql
Normal file
@ -0,0 +1,21 @@
|
||||
USE powerjob-daily;
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `app_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '应用ID',
|
||||
`app_name` varchar(128) not NULL COMMENT '应用名称',
|
||||
`current_server` varchar(255) default null COMMENT 'Server地址,用于负责调度应用的ActorSystem地址',
|
||||
`gmt_create` datetime not null COMMENT '创建时间',
|
||||
`gmt_modified` datetime not null COMMENT '更新时间',
|
||||
`password` varchar(255) not null COMMENT '应用密码',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_app_info` (`app_name`)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci COMMENT ='应用表';
|
||||
|
||||
insert into app_info (app_name, gmt_create, gmt_modified, password) select 'powerjob-worker-samples', current_timestamp(), current_timestamp(), 'powerjob123' from dual where not exists ( select * from app_info where app_name = 'powerjob-worker-samples');
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
@ -1,17 +1,17 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : Local MySQL
|
||||
Source Server : Local@3306
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80021
|
||||
Source Server Version : 80300 (8.3.0)
|
||||
Source Host : localhost:3306
|
||||
Source Schema : powerjob-db-template
|
||||
Source Schema : powerjob4
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80021
|
||||
Target Server Version : 80300 (8.3.0)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 28/11/2020 17:05:50
|
||||
Date: 02/03/2024 18:51:36
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
@ -29,7 +29,7 @@ CREATE TABLE `app_info` (
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `appNameUK` (`app_name`)
|
||||
UNIQUE KEY `uidx01_app_info` (`app_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
@ -48,7 +48,7 @@ CREATE TABLE `container_info` (
|
||||
`status` int DEFAULT NULL,
|
||||
`version` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `IDX8hixyaktlnwil2w9up6b0p898` (`app_id`)
|
||||
KEY `idx01_container_info` (`app_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
@ -66,6 +66,7 @@ CREATE TABLE `instance_info` (
|
||||
`instance_id` bigint DEFAULT NULL,
|
||||
`instance_params` longtext,
|
||||
`job_id` bigint DEFAULT NULL,
|
||||
`job_params` longtext,
|
||||
`last_report_time` bigint DEFAULT NULL,
|
||||
`result` longtext,
|
||||
`running_times` bigint DEFAULT NULL,
|
||||
@ -74,9 +75,9 @@ CREATE TABLE `instance_info` (
|
||||
`type` int DEFAULT NULL,
|
||||
`wf_instance_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `IDX5b1nhpe5je7gc5s1ur200njr7` (`job_id`),
|
||||
KEY `IDXjnji5lrr195kswk6f7mfhinrs` (`app_id`),
|
||||
KEY `IDXa98hq3yu0l863wuotdjl7noum` (`instance_id`)
|
||||
KEY `idx01_instance_info` (`job_id`,`status`),
|
||||
KEY `idx02_instance_info` (`app_id`,`status`),
|
||||
KEY `idx03_instance_info` (`instance_id`,`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
@ -85,17 +86,24 @@ CREATE TABLE `instance_info` (
|
||||
DROP TABLE IF EXISTS `job_info`;
|
||||
CREATE TABLE `job_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`advanced_runtime_config` varchar(255) DEFAULT NULL,
|
||||
`alarm_config` varchar(255) DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`concurrency` int DEFAULT NULL,
|
||||
`designated_workers` varchar(255) DEFAULT NULL,
|
||||
`dispatch_strategy` int DEFAULT NULL,
|
||||
`dispatch_strategy_config` varchar(255) DEFAULT NULL,
|
||||
`execute_type` int DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`instance_retry_num` int DEFAULT NULL,
|
||||
`instance_time_limit` bigint DEFAULT NULL,
|
||||
`job_description` varchar(255) DEFAULT NULL,
|
||||
`job_name` varchar(255) DEFAULT NULL,
|
||||
`job_params` varchar(255) DEFAULT NULL,
|
||||
`job_params` longtext,
|
||||
`lifecycle` varchar(255) DEFAULT NULL,
|
||||
`log_config` varchar(255) DEFAULT NULL,
|
||||
`max_instance_num` int DEFAULT NULL,
|
||||
`max_worker_count` int DEFAULT NULL,
|
||||
`min_cpu_cores` double NOT NULL,
|
||||
@ -103,14 +111,15 @@ CREATE TABLE `job_info` (
|
||||
`min_memory_space` double NOT NULL,
|
||||
`next_trigger_time` bigint DEFAULT NULL,
|
||||
`notify_user_ids` varchar(255) DEFAULT NULL,
|
||||
`processor_info` longtext,
|
||||
`processor_info` varchar(255) DEFAULT NULL,
|
||||
`processor_type` int DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`tag` varchar(255) DEFAULT NULL,
|
||||
`task_retry_num` int DEFAULT NULL,
|
||||
`time_expression` varchar(255) DEFAULT NULL,
|
||||
`time_expression_type` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `IDXk2xprmn3lldmlcb52i36udll1` (`app_id`)
|
||||
KEY `idx01_job_info` (`app_id`,`status`,`time_expression_type`,`next_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
@ -125,8 +134,8 @@ CREATE TABLE `oms_lock` (
|
||||
`max_lock_time` bigint DEFAULT NULL,
|
||||
`ownerip` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `lockNameUK` (`lock_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
UNIQUE KEY `uidx01_oms_lock` (`lock_name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for server_info
|
||||
@ -138,7 +147,8 @@ CREATE TABLE `server_info` (
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`ip` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `UKtk8ytgpl7mpukhnvhbl82kgvy` (`ip`)
|
||||
UNIQUE KEY `uidx01_server_info` (`ip`),
|
||||
KEY `idx01_server_info` (`gmt_modified`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
@ -155,7 +165,9 @@ CREATE TABLE `user_info` (
|
||||
`phone` varchar(255) DEFAULT NULL,
|
||||
`username` varchar(255) DEFAULT NULL,
|
||||
`web_hook` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `uidx01_user_info` (`username`),
|
||||
KEY `uidx02_user_info` (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
@ -165,8 +177,10 @@ DROP TABLE IF EXISTS `workflow_info`;
|
||||
CREATE TABLE `workflow_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`lifecycle` varchar(255) DEFAULT NULL,
|
||||
`max_wf_instance_num` int DEFAULT NULL,
|
||||
`next_trigger_time` bigint DEFAULT NULL,
|
||||
`notify_user_ids` varchar(255) DEFAULT NULL,
|
||||
@ -177,7 +191,7 @@ CREATE TABLE `workflow_info` (
|
||||
`wf_description` varchar(255) DEFAULT NULL,
|
||||
`wf_name` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `IDX7uo5w0e3beeho3fnx9t7eiol3` (`app_id`)
|
||||
KEY `idx01_workflow_info` (`app_id`,`status`,`time_expression_type`,`next_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
@ -193,12 +207,37 @@ CREATE TABLE `workflow_instance_info` (
|
||||
`finished_time` bigint DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`parent_wf_instance_id` bigint DEFAULT NULL,
|
||||
`result` longtext,
|
||||
`status` int DEFAULT NULL,
|
||||
`wf_context` longtext,
|
||||
`wf_init_params` longtext,
|
||||
`wf_instance_id` bigint DEFAULT NULL,
|
||||
`workflow_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_wf_instance` (`wf_instance_id`),
|
||||
KEY `idx01_wf_instance` (`workflow_id`,`status`,`app_id`,`expected_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_node_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_node_info`;
|
||||
CREATE TABLE `workflow_node_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint NOT NULL,
|
||||
`enable` bit(1) NOT NULL,
|
||||
`extra` longtext,
|
||||
`gmt_create` datetime(6) NOT NULL,
|
||||
`gmt_modified` datetime(6) NOT NULL,
|
||||
`job_id` bigint DEFAULT NULL,
|
||||
`node_name` varchar(255) DEFAULT NULL,
|
||||
`node_params` longtext,
|
||||
`skip_when_failed` bit(1) NOT NULL,
|
||||
`type` int DEFAULT NULL,
|
||||
`workflow_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_workflow_node_info` (`workflow_id`,`gmt_create`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
323
others/sql/schema/powerjob_mysql_5.0.1.sql
Normal file
323
others/sql/schema/powerjob_mysql_5.0.1.sql
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : Local@3306
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80300 (8.3.0)
|
||||
Source Host : localhost:3306
|
||||
Source Schema : powerjob5
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80300 (8.3.0)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 16/03/2024 22:07:31
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for app_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `app_info`;
|
||||
CREATE TABLE `app_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_name` varchar(255) DEFAULT NULL,
|
||||
`creator` bigint DEFAULT NULL,
|
||||
`current_server` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`modifier` bigint DEFAULT NULL,
|
||||
`namespace_id` bigint DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`tags` varchar(255) DEFAULT NULL,
|
||||
`title` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_app_info` (`app_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for container_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `container_info`;
|
||||
CREATE TABLE `container_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`container_name` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`last_deploy_time` datetime(6) DEFAULT NULL,
|
||||
`source_info` varchar(255) DEFAULT NULL,
|
||||
`source_type` int DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`version` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_container_info` (`app_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for instance_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `instance_info`;
|
||||
CREATE TABLE `instance_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`actual_trigger_time` bigint DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`expected_trigger_time` bigint DEFAULT NULL,
|
||||
`finished_time` bigint DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`instance_id` bigint DEFAULT NULL,
|
||||
`instance_params` longtext,
|
||||
`job_id` bigint DEFAULT NULL,
|
||||
`job_params` longtext,
|
||||
`last_report_time` bigint DEFAULT NULL,
|
||||
`result` longtext,
|
||||
`running_times` bigint DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`task_tracker_address` varchar(255) DEFAULT NULL,
|
||||
`type` int DEFAULT NULL,
|
||||
`wf_instance_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_instance_info` (`job_id`,`status`),
|
||||
KEY `idx02_instance_info` (`app_id`,`status`),
|
||||
KEY `idx03_instance_info` (`instance_id`,`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for job_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `job_info`;
|
||||
CREATE TABLE `job_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`advanced_runtime_config` varchar(255) DEFAULT NULL,
|
||||
`alarm_config` varchar(255) DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`concurrency` int DEFAULT NULL,
|
||||
`designated_workers` varchar(255) DEFAULT NULL,
|
||||
`dispatch_strategy` int DEFAULT NULL,
|
||||
`dispatch_strategy_config` varchar(255) DEFAULT NULL,
|
||||
`execute_type` int DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`instance_retry_num` int DEFAULT NULL,
|
||||
`instance_time_limit` bigint DEFAULT NULL,
|
||||
`job_description` varchar(255) DEFAULT NULL,
|
||||
`job_name` varchar(255) DEFAULT NULL,
|
||||
`job_params` longtext,
|
||||
`lifecycle` varchar(255) DEFAULT NULL,
|
||||
`log_config` varchar(255) DEFAULT NULL,
|
||||
`max_instance_num` int DEFAULT NULL,
|
||||
`max_worker_count` int DEFAULT NULL,
|
||||
`min_cpu_cores` double NOT NULL,
|
||||
`min_disk_space` double NOT NULL,
|
||||
`min_memory_space` double NOT NULL,
|
||||
`next_trigger_time` bigint DEFAULT NULL,
|
||||
`notify_user_ids` varchar(255) DEFAULT NULL,
|
||||
`processor_info` varchar(255) DEFAULT NULL,
|
||||
`processor_type` int DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`tag` varchar(255) DEFAULT NULL,
|
||||
`task_retry_num` int DEFAULT NULL,
|
||||
`time_expression` varchar(255) DEFAULT NULL,
|
||||
`time_expression_type` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_job_info` (`app_id`,`status`,`time_expression_type`,`next_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for namespace
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `namespace`;
|
||||
CREATE TABLE `namespace` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`code` varchar(255) DEFAULT NULL,
|
||||
`creator` bigint DEFAULT NULL,
|
||||
`dept` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`modifier` bigint DEFAULT NULL,
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`tags` varchar(255) DEFAULT NULL,
|
||||
`token` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_namespace` (`code`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for oms_lock
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `oms_lock`;
|
||||
CREATE TABLE `oms_lock` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`lock_name` varchar(255) DEFAULT NULL,
|
||||
`max_lock_time` bigint DEFAULT NULL,
|
||||
`ownerip` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_oms_lock` (`lock_name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for pwjb_user_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `pwjb_user_info`;
|
||||
CREATE TABLE `pwjb_user_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`username` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_username` (`username`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for server_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `server_info`;
|
||||
CREATE TABLE `server_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`ip` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_server_info` (`ip`),
|
||||
KEY `idx01_server_info` (`gmt_modified`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sundry
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sundry`;
|
||||
CREATE TABLE `sundry` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`content` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`pkey` varchar(255) DEFAULT NULL,
|
||||
`skey` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_sundry` (`pkey`,`skey`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_info`;
|
||||
CREATE TABLE `user_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`account_type` varchar(255) DEFAULT NULL,
|
||||
`email` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`nick` varchar(255) DEFAULT NULL,
|
||||
`origin_username` varchar(255) DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`phone` varchar(255) DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`token_login_verify_info` varchar(255) DEFAULT NULL,
|
||||
`username` varchar(255) DEFAULT NULL,
|
||||
`web_hook` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_user_name` (`username`),
|
||||
KEY `uidx02_user_info` (`email`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_role
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_role`;
|
||||
CREATE TABLE `user_role` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`role` int DEFAULT NULL,
|
||||
`scope` int DEFAULT NULL,
|
||||
`target` bigint DEFAULT NULL,
|
||||
`user_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `uidx01_user_id` (`user_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_info`;
|
||||
CREATE TABLE `workflow_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`lifecycle` varchar(255) DEFAULT NULL,
|
||||
`max_wf_instance_num` int DEFAULT NULL,
|
||||
`next_trigger_time` bigint DEFAULT NULL,
|
||||
`notify_user_ids` varchar(255) DEFAULT NULL,
|
||||
`pedag` longtext,
|
||||
`status` int DEFAULT NULL,
|
||||
`time_expression` varchar(255) DEFAULT NULL,
|
||||
`time_expression_type` int DEFAULT NULL,
|
||||
`wf_description` varchar(255) DEFAULT NULL,
|
||||
`wf_name` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_workflow_info` (`app_id`,`status`,`time_expression_type`,`next_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_instance_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_instance_info`;
|
||||
CREATE TABLE `workflow_instance_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`actual_trigger_time` bigint DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`dag` longtext,
|
||||
`expected_trigger_time` bigint DEFAULT NULL,
|
||||
`finished_time` bigint DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`parent_wf_instance_id` bigint DEFAULT NULL,
|
||||
`result` longtext,
|
||||
`status` int DEFAULT NULL,
|
||||
`wf_context` longtext,
|
||||
`wf_init_params` longtext,
|
||||
`wf_instance_id` bigint DEFAULT NULL,
|
||||
`workflow_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_wf_instance` (`wf_instance_id`),
|
||||
KEY `idx01_wf_instance` (`workflow_id`,`status`,`app_id`,`expected_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_node_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_node_info`;
|
||||
CREATE TABLE `workflow_node_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint NOT NULL,
|
||||
`enable` bit(1) NOT NULL,
|
||||
`extra` longtext,
|
||||
`gmt_create` datetime(6) NOT NULL,
|
||||
`gmt_modified` datetime(6) NOT NULL,
|
||||
`job_id` bigint DEFAULT NULL,
|
||||
`node_name` varchar(255) DEFAULT NULL,
|
||||
`node_params` longtext,
|
||||
`skip_when_failed` bit(1) NOT NULL,
|
||||
`type` int DEFAULT NULL,
|
||||
`workflow_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_workflow_node_info` (`workflow_id`,`gmt_create`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
323
others/sql/schema/powerjob_mysql_5.1.0.sql
Normal file
323
others/sql/schema/powerjob_mysql_5.1.0.sql
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : Local@3306
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 80300 (8.3.0)
|
||||
Source Host : localhost:3306
|
||||
Source Schema : powerjob5
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 80300 (8.3.0)
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 11/08/2024 23:23:30
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for app_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `app_info`;
|
||||
CREATE TABLE `app_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_name` varchar(255) DEFAULT NULL,
|
||||
`creator` bigint DEFAULT NULL,
|
||||
`current_server` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`modifier` bigint DEFAULT NULL,
|
||||
`namespace_id` bigint DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`tags` varchar(255) DEFAULT NULL,
|
||||
`title` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_app_info` (`app_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for container_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `container_info`;
|
||||
CREATE TABLE `container_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`container_name` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`last_deploy_time` datetime(6) DEFAULT NULL,
|
||||
`source_info` varchar(255) DEFAULT NULL,
|
||||
`source_type` int DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`version` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_container_info` (`app_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for instance_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `instance_info`;
|
||||
CREATE TABLE `instance_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`actual_trigger_time` bigint DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`expected_trigger_time` bigint DEFAULT NULL,
|
||||
`finished_time` bigint DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`instance_id` bigint DEFAULT NULL,
|
||||
`instance_params` longtext,
|
||||
`job_id` bigint DEFAULT NULL,
|
||||
`job_params` longtext,
|
||||
`last_report_time` bigint DEFAULT NULL,
|
||||
`result` longtext,
|
||||
`running_times` bigint DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`task_tracker_address` varchar(255) DEFAULT NULL,
|
||||
`type` int DEFAULT NULL,
|
||||
`wf_instance_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_instance_info` (`job_id`,`status`),
|
||||
KEY `idx02_instance_info` (`app_id`,`status`),
|
||||
KEY `idx03_instance_info` (`instance_id`,`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for job_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `job_info`;
|
||||
CREATE TABLE `job_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`advanced_runtime_config` varchar(255) DEFAULT NULL,
|
||||
`alarm_config` varchar(255) DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`concurrency` int DEFAULT NULL,
|
||||
`designated_workers` varchar(255) DEFAULT NULL,
|
||||
`dispatch_strategy` int DEFAULT NULL,
|
||||
`dispatch_strategy_config` varchar(255) DEFAULT NULL,
|
||||
`execute_type` int DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`instance_retry_num` int DEFAULT NULL,
|
||||
`instance_time_limit` bigint DEFAULT NULL,
|
||||
`job_description` varchar(255) DEFAULT NULL,
|
||||
`job_name` varchar(255) DEFAULT NULL,
|
||||
`job_params` longtext,
|
||||
`lifecycle` varchar(255) DEFAULT NULL,
|
||||
`log_config` varchar(255) DEFAULT NULL,
|
||||
`max_instance_num` int DEFAULT NULL,
|
||||
`max_worker_count` int DEFAULT NULL,
|
||||
`min_cpu_cores` double NOT NULL,
|
||||
`min_disk_space` double NOT NULL,
|
||||
`min_memory_space` double NOT NULL,
|
||||
`next_trigger_time` bigint DEFAULT NULL,
|
||||
`notify_user_ids` varchar(255) DEFAULT NULL,
|
||||
`processor_info` varchar(255) DEFAULT NULL,
|
||||
`processor_type` int DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`tag` varchar(255) DEFAULT NULL,
|
||||
`task_retry_num` int DEFAULT NULL,
|
||||
`time_expression` varchar(255) DEFAULT NULL,
|
||||
`time_expression_type` int DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_job_info` (`app_id`,`status`,`time_expression_type`,`next_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for namespace
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `namespace`;
|
||||
CREATE TABLE `namespace` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`code` varchar(255) DEFAULT NULL,
|
||||
`creator` bigint DEFAULT NULL,
|
||||
`dept` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`modifier` bigint DEFAULT NULL,
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`tags` varchar(255) DEFAULT NULL,
|
||||
`token` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_namespace` (`code`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for oms_lock
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `oms_lock`;
|
||||
CREATE TABLE `oms_lock` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`lock_name` varchar(255) DEFAULT NULL,
|
||||
`max_lock_time` bigint DEFAULT NULL,
|
||||
`ownerip` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_oms_lock` (`lock_name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for pwjb_user_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `pwjb_user_info`;
|
||||
CREATE TABLE `pwjb_user_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`username` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_username` (`username`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for server_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `server_info`;
|
||||
CREATE TABLE `server_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`ip` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_server_info` (`ip`),
|
||||
KEY `idx01_server_info` (`gmt_modified`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for sundry
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `sundry`;
|
||||
CREATE TABLE `sundry` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`content` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`pkey` varchar(255) DEFAULT NULL,
|
||||
`skey` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_sundry` (`pkey`,`skey`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_info`;
|
||||
CREATE TABLE `user_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`account_type` varchar(255) DEFAULT NULL,
|
||||
`email` varchar(255) DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`nick` varchar(255) DEFAULT NULL,
|
||||
`origin_username` varchar(255) DEFAULT NULL,
|
||||
`password` varchar(255) DEFAULT NULL,
|
||||
`phone` varchar(255) DEFAULT NULL,
|
||||
`status` int DEFAULT NULL,
|
||||
`token_login_verify_info` varchar(255) DEFAULT NULL,
|
||||
`username` varchar(255) DEFAULT NULL,
|
||||
`web_hook` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_user_name` (`username`),
|
||||
KEY `uidx02_user_info` (`email`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for user_role
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `user_role`;
|
||||
CREATE TABLE `user_role` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`role` int DEFAULT NULL,
|
||||
`scope` int DEFAULT NULL,
|
||||
`target` bigint DEFAULT NULL,
|
||||
`user_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `uidx01_user_id` (`user_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_info`;
|
||||
CREATE TABLE `workflow_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`extra` varchar(255) DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`lifecycle` varchar(255) DEFAULT NULL,
|
||||
`max_wf_instance_num` int DEFAULT NULL,
|
||||
`next_trigger_time` bigint DEFAULT NULL,
|
||||
`notify_user_ids` varchar(255) DEFAULT NULL,
|
||||
`pedag` longtext,
|
||||
`status` int DEFAULT NULL,
|
||||
`time_expression` varchar(255) DEFAULT NULL,
|
||||
`time_expression_type` int DEFAULT NULL,
|
||||
`wf_description` varchar(255) DEFAULT NULL,
|
||||
`wf_name` varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_workflow_info` (`app_id`,`status`,`time_expression_type`,`next_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_instance_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_instance_info`;
|
||||
CREATE TABLE `workflow_instance_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`actual_trigger_time` bigint DEFAULT NULL,
|
||||
`app_id` bigint DEFAULT NULL,
|
||||
`dag` longtext,
|
||||
`expected_trigger_time` bigint DEFAULT NULL,
|
||||
`finished_time` bigint DEFAULT NULL,
|
||||
`gmt_create` datetime(6) DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) DEFAULT NULL,
|
||||
`parent_wf_instance_id` bigint DEFAULT NULL,
|
||||
`result` longtext,
|
||||
`status` int DEFAULT NULL,
|
||||
`wf_context` longtext,
|
||||
`wf_init_params` longtext,
|
||||
`wf_instance_id` bigint DEFAULT NULL,
|
||||
`workflow_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uidx01_wf_instance` (`wf_instance_id`),
|
||||
KEY `idx01_wf_instance` (`workflow_id`,`status`,`app_id`,`expected_trigger_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for workflow_node_info
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `workflow_node_info`;
|
||||
CREATE TABLE `workflow_node_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`app_id` bigint NOT NULL,
|
||||
`enable` bit(1) NOT NULL,
|
||||
`extra` longtext,
|
||||
`gmt_create` datetime(6) NOT NULL,
|
||||
`gmt_modified` datetime(6) NOT NULL,
|
||||
`job_id` bigint DEFAULT NULL,
|
||||
`node_name` varchar(255) DEFAULT NULL,
|
||||
`node_params` longtext,
|
||||
`skip_when_failed` bit(1) NOT NULL,
|
||||
`type` int DEFAULT NULL,
|
||||
`workflow_id` bigint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx01_workflow_node_info` (`workflow_id`,`gmt_create`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
7
others/sql/upgrade/README.md
Normal file
7
others/sql/upgrade/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
由于存在不同数据库、不同版本的升级,官方能给出的 upgrade SQL 相对有限,大家可参考以下方式自行生成升级 SQL:
|
||||
|
||||
- 【官方脚本】参考官方每个版本的数据库全库建表文件(项目 others - sql - schema),自行进行字段 DIFF
|
||||
|
||||
- 【自己动手版】导出当前您的 powerjob 数据库表结构,同时创建一个测试库,让 5.x 版本的 server 直连该测试库,自动建表。分别拿到两个版本的表结构 SQL 后,借用工具生产 update SQL 即可(navigate 等数据库管理软件均支持结构对比)
|
||||
|
||||
参考文档:https://www.yuque.com/powerjob/guidence/upgrade
|
10
others/sql/upgrade/v4.0.x-v4.1.x.sql
Normal file
10
others/sql/upgrade/v4.0.x-v4.1.x.sql
Normal file
@ -0,0 +1,10 @@
|
||||
-- Upgrade SQL FROM 4.0.x to 4.1.x
|
||||
-- ----------------------------
|
||||
-- Table change for workflow_instance_info
|
||||
-- ----------------------------
|
||||
alter table workflow_instance_info
|
||||
add parent_wf_instance_id bigint default null null comment '上层工作流实例ID';
|
||||
-- ----------------------------
|
||||
-- Table change for job_info
|
||||
-- ----------------------------
|
||||
alter table job_info add alarm_config varchar(512) comment '告警配置' default null;
|
6
others/sql/upgrade/v4.1.x-v4.2.x.sql
Normal file
6
others/sql/upgrade/v4.1.x-v4.2.x.sql
Normal file
@ -0,0 +1,6 @@
|
||||
-- Upgrade SQL FROM 4.1.x to 4.2.x
|
||||
-- ----------------------------
|
||||
-- Table change for job_info
|
||||
-- ----------------------------
|
||||
alter table job_info add tag varchar(255) comment 'TAG' default null;
|
||||
alter table job_info add log_config varchar(255) comment 'logConfig' default null;
|
6
others/sql/upgrade/v4.3.7-v4.3.8.sql
Normal file
6
others/sql/upgrade/v4.3.7-v4.3.8.sql
Normal file
@ -0,0 +1,6 @@
|
||||
-- Upgrade SQL FROM 4.3.7 to 4.3.8
|
||||
-- ----------------------------
|
||||
-- Table change for job_info
|
||||
-- ----------------------------
|
||||
alter table job_info add dispatch_strategy_config varchar(255) comment 'dispatch_strategy_config' default null;
|
||||
alter table job_info add advanced_runtime_config varchar(255) comment 'advanced_runtime_config' default null;
|
88
others/sql/upgrade/v4.3.x-v5.0.x.sql
Normal file
88
others/sql/upgrade/v4.3.x-v5.0.x.sql
Normal file
@ -0,0 +1,88 @@
|
||||
-- Upgrade SQL FROM 4.1.x to 4.2.x
|
||||
-- ----------------------------
|
||||
-- Table change for app_info
|
||||
-- ----------------------------
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
|
||||
ALTER TABLE `app_info` ADD COLUMN `creator` bigint NULL DEFAULT NULL;
|
||||
ALTER TABLE `app_info` ADD COLUMN `extra` varchar(255) NULL DEFAULT NULL;
|
||||
ALTER TABLE `app_info` ADD COLUMN `modifier` bigint NULL DEFAULT NULL;
|
||||
ALTER TABLE `app_info` ADD COLUMN `namespace_id` bigint NULL DEFAULT NULL;
|
||||
ALTER TABLE `app_info` ADD COLUMN `tags` varchar(255) NULL DEFAULT NULL;
|
||||
ALTER TABLE `app_info` ADD COLUMN `title` varchar(255) NULL DEFAULT NULL;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table change for user_info
|
||||
-- ----------------------------
|
||||
ALTER TABLE `user_info` ADD COLUMN `account_type` varchar(255) NULL DEFAULT NULL;
|
||||
ALTER TABLE `user_info` ADD COLUMN `nick` varchar(255) NULL DEFAULT NULL;
|
||||
ALTER TABLE `user_info` ADD COLUMN `origin_username` varchar(255) NULL DEFAULT NULL;
|
||||
ALTER TABLE `user_info` ADD COLUMN `token_login_verify_info` varchar(255) NULL DEFAULT NULL;
|
||||
ALTER TABLE `user_info` ADD UNIQUE INDEX `uidx01_user_name`(`username` ASC) USING BTREE;
|
||||
|
||||
-- ----------------------------
|
||||
-- new table 'namespace'
|
||||
-- ----------------------------
|
||||
CREATE TABLE `namespace` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`code` varchar(255) NULL DEFAULT NULL,
|
||||
`creator` bigint NULL DEFAULT NULL,
|
||||
`dept` varchar(255) NULL DEFAULT NULL,
|
||||
`extra` varchar(255) NULL DEFAULT NULL,
|
||||
`gmt_create` datetime(6) NULL DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) NULL DEFAULT NULL,
|
||||
`modifier` bigint NULL DEFAULT NULL,
|
||||
`name` varchar(255) NULL DEFAULT NULL,
|
||||
`status` int NULL DEFAULT NULL,
|
||||
`tags` varchar(255) NULL DEFAULT NULL,
|
||||
`token` varchar(255) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uidx01_namespace`(`code` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- new table 'pwjb_user_info'
|
||||
-- ----------------------------
|
||||
CREATE TABLE `pwjb_user_info` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`extra` varchar(255) NULL DEFAULT NULL,
|
||||
`gmt_create` datetime(6) NULL DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) NULL DEFAULT NULL,
|
||||
`password` varchar(255) NULL DEFAULT NULL,
|
||||
`username` varchar(255) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uidx01_username`(`username` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
-- ----------------------------
|
||||
-- new table 'sundry'
|
||||
-- ----------------------------
|
||||
CREATE TABLE `sundry` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`content` varchar(255) NULL DEFAULT NULL,
|
||||
`extra` varchar(255) NULL DEFAULT NULL,
|
||||
`gmt_create` datetime(6) NULL DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) NULL DEFAULT NULL,
|
||||
`pkey` varchar(255) NULL DEFAULT NULL,
|
||||
`skey` varchar(255) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uidx01_sundry`(`pkey` ASC, `skey` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
-- new table 'user_role'
|
||||
-- ----------------------------
|
||||
CREATE TABLE `user_role` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||
`extra` varchar(255) NULL DEFAULT NULL,
|
||||
`gmt_create` datetime(6) NULL DEFAULT NULL,
|
||||
`gmt_modified` datetime(6) NULL DEFAULT NULL,
|
||||
`role` int NULL DEFAULT NULL,
|
||||
`scope` int NULL DEFAULT NULL,
|
||||
`target` bigint NULL DEFAULT NULL,
|
||||
`user_id` bigint NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `uidx01_user_id`(`user_id` ASC) USING BTREE
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
39
pom.xml
39
pom.xml
@ -4,13 +4,13 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.github.kfcfans</groupId>
|
||||
<groupId>tech.powerjob</groupId>
|
||||
<artifactId>powerjob</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>5.1.1</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>powerjob</name>
|
||||
<url>http://www.powerjob.tech</url>
|
||||
<description>Distributed scheduling and execution framework</description>
|
||||
<description>Enterprise job scheduling middleware with distributed computing ability.</description>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
@ -19,8 +19,8 @@
|
||||
</license>
|
||||
</licenses>
|
||||
<scm>
|
||||
<url>https://github.com/KFCFans/PowerJob</url>
|
||||
<connection>https://github.com/KFCFans/PowerJob.git</connection>
|
||||
<url>https://github.com/PowerJob/PowerJob</url>
|
||||
<connection>https://github.com/PowerJob/PowerJob.git</connection>
|
||||
</scm>
|
||||
|
||||
<developers>
|
||||
@ -43,6 +43,8 @@
|
||||
<module>powerjob-worker-agent</module>
|
||||
<module>powerjob-worker-spring-boot-starter</module>
|
||||
<module>powerjob-worker-samples</module>
|
||||
<module>powerjob-official-processors</module>
|
||||
<module>powerjob-remote</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
@ -87,7 +89,7 @@
|
||||
<testTarget>${java.version}</testTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- 打包源码 -->
|
||||
<!-- Package source codes -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
@ -121,9 +123,9 @@
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>${maven-javadoc-plugin.version}</version>
|
||||
<configuration>
|
||||
<!-- JavaDoc 编译错误不影响正常构建 -->
|
||||
<!-- Prevent JavaDoc error from affecting building project. -->
|
||||
<failOnError>false</failOnError>
|
||||
<!-- 非严格模式...以后要好好按格式写注释啊... -->
|
||||
<!-- Non-strict mode -->
|
||||
<additionalJOption>-Xdoclint:none</additionalJOption>
|
||||
</configuration>
|
||||
<executions>
|
||||
@ -149,22 +151,33 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.7</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>ossrh</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>ossrh</id>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
|
||||
<!-- 本地使用 -->
|
||||
<!-- Local profile -->
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
@ -173,7 +186,7 @@
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- 编译插件 -->
|
||||
<!-- Maven compiler plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
@ -185,7 +198,7 @@
|
||||
<testTarget>${java.version}</testTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- 编辑 MANIFEST.MF -->
|
||||
<!-- Edit MANIFEST.MF -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
|
@ -4,19 +4,20 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>powerjob</artifactId>
|
||||
<groupId>com.github.kfcfans</groupId>
|
||||
<version>2.0.0</version>
|
||||
<groupId>tech.powerjob</groupId>
|
||||
<version>5.1.1</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>powerjob-client</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<version>5.1.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<junit.version>5.6.1</junit.version>
|
||||
<fastjson.version>1.2.68</fastjson.version>
|
||||
<powerjob.common.version>3.4.0</powerjob.common.version>
|
||||
<junit.version>5.9.1</junit.version>
|
||||
<logback.version>1.2.13</logback.version>
|
||||
<fastjson.version>1.2.83</fastjson.version>
|
||||
<powerjob.common.version>5.1.1</powerjob.common.version>
|
||||
|
||||
<mvn.shade.plugin.version>3.2.4</mvn.shade.plugin.version>
|
||||
</properties>
|
||||
@ -32,18 +33,25 @@
|
||||
|
||||
<!-- oms-common -->
|
||||
<dependency>
|
||||
<groupId>com.github.kfcfans</groupId>
|
||||
<groupId>tech.powerjob</groupId>
|
||||
<artifactId>powerjob-common</artifactId>
|
||||
<version>${powerjob.common.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Junit 测试 -->
|
||||
<!-- Junit tests -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- log for test stage -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -1,444 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.client;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.kfcfans.powerjob.common.InstanceStatus;
|
||||
import com.github.kfcfans.powerjob.common.OmsConstant;
|
||||
import com.github.kfcfans.powerjob.common.OpenAPIConstant;
|
||||
import com.github.kfcfans.powerjob.common.PowerJobException;
|
||||
import com.github.kfcfans.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import com.github.kfcfans.powerjob.common.request.http.SaveWorkflowRequest;
|
||||
import com.github.kfcfans.powerjob.common.response.*;
|
||||
import com.github.kfcfans.powerjob.common.utils.CommonUtils;
|
||||
import com.github.kfcfans.powerjob.common.utils.HttpUtils;
|
||||
import com.github.kfcfans.powerjob.common.utils.JsonUtils;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.RequestBody;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.github.kfcfans.powerjob.client.TypeStore.*;
|
||||
|
||||
/**
|
||||
* OpenAPI 客户端
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/15
|
||||
*/
|
||||
@Slf4j
|
||||
public class OhMyClient {
|
||||
|
||||
private Long appId;
|
||||
private String currentAddress;
|
||||
private final List<String> allAddress;
|
||||
|
||||
private static final String URL_PATTERN = "http://%s%s%s";
|
||||
|
||||
/**
|
||||
* 初始化 OhMyClient 客户端
|
||||
* @param domain 比如 www.powerjob-server.com(内网域名,自行完成 DNS & Proxy)
|
||||
* @param appName 负责的应用名称
|
||||
*/
|
||||
public OhMyClient(String domain, String appName, String password) {
|
||||
this(Lists.newArrayList(domain), appName, password);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化 OhMyClient 客户端
|
||||
* @param addressList IP:Port 列表
|
||||
* @param appName 负责的应用名称
|
||||
*/
|
||||
public OhMyClient(List<String> addressList, String appName, String password) {
|
||||
|
||||
CommonUtils.requireNonNull(addressList, "addressList can't be null!");
|
||||
CommonUtils.requireNonNull(appName, "appName can't be null");
|
||||
|
||||
allAddress = addressList;
|
||||
for (String addr : addressList) {
|
||||
String url = getUrl(OpenAPIConstant.ASSERT, addr);
|
||||
try {
|
||||
String result = assertApp(appName, password, url);
|
||||
if (StringUtils.isNotEmpty(result)) {
|
||||
ResultDTO<Long> resultDTO = JSONObject.parseObject(result, LONG_RESULT_TYPE);
|
||||
if (resultDTO.isSuccess()) {
|
||||
appId = resultDTO.getData();
|
||||
currentAddress = addr;
|
||||
break;
|
||||
}else {
|
||||
throw new PowerJobException(resultDTO.getMessage());
|
||||
}
|
||||
}
|
||||
}catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(currentAddress)) {
|
||||
throw new PowerJobException("no server available");
|
||||
}
|
||||
log.info("[OhMyClient] {}'s OhMyClient bootstrap successfully, using server: {}", appName, currentAddress);
|
||||
}
|
||||
|
||||
private static String assertApp(String appName, String password, String url) throws IOException {
|
||||
FormBody.Builder builder = new FormBody.Builder()
|
||||
.add("appName", appName);
|
||||
if (password != null) {
|
||||
builder.add("password", password);
|
||||
}
|
||||
return HttpUtils.post(url, builder.build());
|
||||
}
|
||||
|
||||
|
||||
private static String getUrl(String path, String address) {
|
||||
return String.format(URL_PATTERN, address, OpenAPIConstant.WEB_PATH, path);
|
||||
}
|
||||
|
||||
/* ************* Job 区 ************* */
|
||||
|
||||
/**
|
||||
* 保存任务(包括创建与修改)
|
||||
* @param request 任务详细参数
|
||||
* @return 创建的任务ID
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Long> saveJob(SaveJobInfoRequest request) throws PowerJobException {
|
||||
|
||||
request.setAppId(appId);
|
||||
MediaType jsonType = MediaType.parse("application/json; charset=utf-8");
|
||||
String json = JSONObject.toJSONString(request);
|
||||
String post = postHA(OpenAPIConstant.SAVE_JOB, RequestBody.create(jsonType, json));
|
||||
return JSONObject.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 jobId 查询任务信息
|
||||
* @param jobId 任务ID
|
||||
* @return 任务详细信息
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<JobInfoDTO> fetchJob(Long jobId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("jobId", jobId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.FETCH_JOB, body);
|
||||
return JSONObject.parseObject(post, JOB_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用某个任务
|
||||
* @param jobId 任务ID
|
||||
* @return 标准返回对象
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> disableJob(Long jobId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("jobId", jobId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.DISABLE_JOB, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用某个任务
|
||||
* @param jobId 任务ID
|
||||
* @return 标准返回对象
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> enableJob(Long jobId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("jobId", jobId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.ENABLE_JOB, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除某个任务
|
||||
* @param jobId 任务ID
|
||||
* @return 标准返回对象
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> deleteJob(Long jobId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("jobId", jobId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.DELETE_JOB, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行某个任务
|
||||
* @param jobId 任务ID
|
||||
* @param instanceParams 任务实例的参数
|
||||
* @param delayMS 延迟时间,单位毫秒
|
||||
* @return 任务实例ID(instanceId)
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Long> runJob(Long jobId, String instanceParams, long delayMS) throws PowerJobException {
|
||||
FormBody.Builder builder = new FormBody.Builder()
|
||||
.add("jobId", jobId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.add("delay", String.valueOf(delayMS));
|
||||
|
||||
if (StringUtils.isNotEmpty(instanceParams)) {
|
||||
builder.add("instanceParams", instanceParams);
|
||||
}
|
||||
String post = postHA(OpenAPIConstant.RUN_JOB, builder.build());
|
||||
return JSONObject.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
public ResultDTO<Long> runJob(Long jobId) throws PowerJobException {
|
||||
return runJob(jobId, null, 0);
|
||||
}
|
||||
|
||||
/* ************* Instance 区 ************* */
|
||||
/**
|
||||
* 停止应用实例
|
||||
* @param instanceId 应用实例ID
|
||||
* @return true 停止成功,false 停止失败
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> stopInstance(Long instanceId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("instanceId", instanceId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.STOP_INSTANCE, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消任务实例
|
||||
* 接口使用条件:调用接口时间与待取消任务的预计执行时间有一定时间间隔,否则不保证可靠性!
|
||||
* @param instanceId 任务实例ID
|
||||
* @return true 代表取消成功,false 取消失败
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> cancelInstance(Long instanceId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("instanceId", instanceId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.CANCEL_INSTANCE, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重试任务实例
|
||||
* 只有完成状态(成功、失败、手动停止、被取消)的任务才能被重试,且暂不支持工作流内任务实例的重试
|
||||
* @param instanceId 任务实例ID
|
||||
* @return true 代表取消成功,false 取消失败
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> retryInstance(Long instanceId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("instanceId", instanceId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.RETRY_INSTANCE, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询任务实例状态
|
||||
* @param instanceId 应用实例ID
|
||||
* @return {@link InstanceStatus} 的枚举值
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Integer> fetchInstanceStatus(Long instanceId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("instanceId", instanceId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.FETCH_INSTANCE_STATUS, body);
|
||||
return JSONObject.parseObject(post, INTEGER_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询任务实例的信息
|
||||
* @param instanceId 任务实例ID
|
||||
* @return 任务实例信息
|
||||
* @throws PowerJobException 潜在的异常
|
||||
*/
|
||||
public ResultDTO<InstanceInfoDTO> fetchInstanceInfo(Long instanceId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("instanceId", instanceId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.FETCH_INSTANCE_INFO, body);
|
||||
return JSONObject.parseObject(post, INSTANCE_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/* ************* Workflow 区 ************* */
|
||||
/**
|
||||
* 保存工作流(包括创建和修改)
|
||||
* @param request 创建/修改 Workflow 请求
|
||||
* @return 工作流ID
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Long> saveWorkflow(SaveWorkflowRequest request) throws PowerJobException {
|
||||
request.setAppId(appId);
|
||||
MediaType jsonType = MediaType.parse(OmsConstant.JSON_MEDIA_TYPE);
|
||||
// 中坑记录:用 FastJSON 序列化会导致 Server 接收时 pEWorkflowDAG 为 null,无语.jpg
|
||||
String json = JsonUtils.toJSONStringUnsafe(request);
|
||||
String post = postHA(OpenAPIConstant.SAVE_WORKFLOW, RequestBody.create(jsonType, json));
|
||||
return JSONObject.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 workflowId 查询工作流信息
|
||||
* @param workflowId workflowId
|
||||
* @return 工作流信息
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<WorkflowInfoDTO> fetchWorkflow(Long workflowId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("workflowId", workflowId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.FETCH_WORKFLOW, body);
|
||||
return JSONObject.parseObject(post, WF_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用某个工作流
|
||||
* @param workflowId 工作流ID
|
||||
* @return 标准返回对象
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> disableWorkflow(Long workflowId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("workflowId", workflowId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.DISABLE_WORKFLOW, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用某个工作流
|
||||
* @param workflowId workflowId
|
||||
* @return 标准返回对象
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> enableWorkflow(Long workflowId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("workflowId", workflowId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.ENABLE_WORKFLOW, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除某个工作流
|
||||
* @param workflowId workflowId
|
||||
* @return 标准返回对象
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> deleteWorkflow(Long workflowId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("workflowId", workflowId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.DELETE_WORKFLOW, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行工作流
|
||||
* @param workflowId 工作流ID
|
||||
* @param initParams 启动参数
|
||||
* @param delayMS 延迟时间,单位毫秒 ms
|
||||
* @return 工作流实例ID
|
||||
* @throws PowerJobException 异常信息
|
||||
*/
|
||||
public ResultDTO<Long> runWorkflow(Long workflowId, String initParams, long delayMS) throws PowerJobException {
|
||||
FormBody.Builder builder = new FormBody.Builder()
|
||||
.add("workflowId", workflowId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.add("delay", String.valueOf(delayMS));
|
||||
if (StringUtils.isNotEmpty(initParams)) {
|
||||
builder.add("initParams", initParams);
|
||||
}
|
||||
String post = postHA(OpenAPIConstant.RUN_WORKFLOW, builder.build());
|
||||
return JSONObject.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
public ResultDTO<Long> runWorkflow(Long workflowId) throws PowerJobException {
|
||||
return runWorkflow(workflowId, null, 0);
|
||||
}
|
||||
|
||||
/* ************* Workflow Instance 区 ************* */
|
||||
/**
|
||||
* 停止应用实例
|
||||
* @param wfInstanceId 工作流实例ID
|
||||
* @return true 停止成功 ; false 停止失败
|
||||
* @throws PowerJobException 异常
|
||||
*/
|
||||
public ResultDTO<Void> stopWorkflowInstance(Long wfInstanceId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("wfInstanceId", wfInstanceId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.STOP_WORKFLOW_INSTANCE, body);
|
||||
return JSONObject.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询任务实例的信息
|
||||
* @param wfInstanceId 任务实例ID
|
||||
* @return 任务实例信息
|
||||
* @throws PowerJobException 潜在的异常
|
||||
*/
|
||||
public ResultDTO<WorkflowInstanceInfoDTO> fetchWorkflowInstanceInfo(Long wfInstanceId) throws PowerJobException {
|
||||
RequestBody body = new FormBody.Builder()
|
||||
.add("wfInstanceId", wfInstanceId.toString())
|
||||
.add("appId", appId.toString())
|
||||
.build();
|
||||
String post = postHA(OpenAPIConstant.FETCH_WORKFLOW_INSTANCE_INFO, body);
|
||||
return JSONObject.parseObject(post, WF_INSTANCE_RESULT_TYPE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String postHA(String path, RequestBody requestBody) {
|
||||
|
||||
// 先尝试默认地址
|
||||
String url = getUrl(path, currentAddress);
|
||||
try {
|
||||
String res = HttpUtils.post(url, requestBody);
|
||||
if (StringUtils.isNotEmpty(res)) {
|
||||
return res;
|
||||
}
|
||||
}catch (IOException e) {
|
||||
log.warn("[OhMyClient] request url:{} failed, reason is {}.", url, e.toString());
|
||||
}
|
||||
|
||||
// 失败,开始重试
|
||||
for (String addr : allAddress) {
|
||||
if (Objects.equals(addr, currentAddress)) {
|
||||
continue;
|
||||
}
|
||||
url = getUrl(path, addr);
|
||||
try {
|
||||
String res = HttpUtils.post(url, requestBody);
|
||||
if (StringUtils.isNotEmpty(res)) {
|
||||
log.warn("[OhMyClient] server change: from({}) -> to({}).", currentAddress, addr);
|
||||
currentAddress = addr;
|
||||
return res;
|
||||
}
|
||||
}catch (IOException e) {
|
||||
log.warn("[OhMyClient] request url:{} failed, reason is {}.", url, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
log.error("[OhMyClient] do post for path: {} failed because of no server available in {}.", path, allAddress);
|
||||
throw new PowerJobException("no server available when send post");
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.client;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.github.kfcfans.powerjob.common.response.*;
|
||||
|
||||
/**
|
||||
* 类型工厂
|
||||
*
|
||||
* @author tjq
|
||||
* @since 11/7/20
|
||||
*/
|
||||
public class TypeStore {
|
||||
|
||||
public static final TypeReference<ResultDTO<Void>> VOID_RESULT_TYPE = new TypeReference<ResultDTO<Void>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<Integer>> INTEGER_RESULT_TYPE = new TypeReference<ResultDTO<Integer>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<Long>> LONG_RESULT_TYPE = new TypeReference<ResultDTO<Long>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<JobInfoDTO>> JOB_RESULT_TYPE = new TypeReference<ResultDTO<JobInfoDTO>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<InstanceInfoDTO>> INSTANCE_RESULT_TYPE = new TypeReference<ResultDTO<InstanceInfoDTO>>() {};
|
||||
|
||||
public static final TypeReference<ResultDTO<WorkflowInfoDTO>> WF_RESULT_TYPE = new TypeReference<ResultDTO<WorkflowInfoDTO>>() {};
|
||||
|
||||
public static final TypeReference<ResultDTO<WorkflowInstanceInfoDTO>> WF_INSTANCE_RESULT_TYPE = new TypeReference<ResultDTO<WorkflowInstanceInfoDTO>>() {};
|
||||
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package tech.powerjob.client;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.experimental.Accessors;
|
||||
import tech.powerjob.client.common.Protocol;
|
||||
import tech.powerjob.client.extension.ClientExtension;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 客户端配置
|
||||
*
|
||||
* @author 程序帕鲁
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@Accessors(chain = true)
|
||||
public class ClientConfig implements Serializable {
|
||||
|
||||
/**
|
||||
* 执行器 AppName
|
||||
*/
|
||||
private String appName;
|
||||
|
||||
/**
|
||||
* 执行器密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 地址列表,支持格式:
|
||||
* - IP:Port, eg: 192.168.1.1:7700
|
||||
* - 域名, eg: powerjob.apple-inc.com
|
||||
*/
|
||||
private List<String> addressList;
|
||||
|
||||
/**
|
||||
* 客户端通讯协议
|
||||
*/
|
||||
private Protocol protocol = Protocol.HTTP;
|
||||
|
||||
/**
|
||||
* 连接超时时间
|
||||
*/
|
||||
private Integer connectionTimeout;
|
||||
/**
|
||||
* 指定了等待服务器响应数据的最长时间。更具体地说,这是从服务器开始返回响应数据(包括HTTP头和数据)后,客户端读取数据的超时时间
|
||||
*/
|
||||
private Integer readTimeout;
|
||||
/**
|
||||
* 指定了向服务器发送数据的最长时间。这是从客户端开始发送数据(如POST请求的正文)到数据完全发送出去的时间
|
||||
*/
|
||||
private Integer writeTimeout;
|
||||
|
||||
/**
|
||||
* 默认携带的请求头
|
||||
* 用于流量被基础设施识别
|
||||
*/
|
||||
private Map<String, String> defaultHeaders;
|
||||
|
||||
/**
|
||||
* 客户端行为扩展
|
||||
*/
|
||||
private ClientExtension clientExtension;
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package tech.powerjob.client;
|
||||
|
||||
import tech.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import tech.powerjob.common.request.http.SaveWorkflowNodeRequest;
|
||||
import tech.powerjob.common.request.http.SaveWorkflowRequest;
|
||||
import tech.powerjob.common.request.query.InstancePageQuery;
|
||||
import tech.powerjob.common.request.query.JobInfoQuery;
|
||||
import tech.powerjob.common.response.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PowerJobClient, the client for OpenAPI.
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2023/3/5
|
||||
*/
|
||||
public interface IPowerJobClient {
|
||||
|
||||
/* ************* Job 区 ************* */
|
||||
|
||||
ResultDTO<SaveJobInfoRequest> exportJob(Long jobId);
|
||||
|
||||
ResultDTO<Long> saveJob(SaveJobInfoRequest request);
|
||||
|
||||
ResultDTO<Long> copyJob(Long jobId);
|
||||
|
||||
ResultDTO<JobInfoDTO> fetchJob(Long jobId);
|
||||
|
||||
ResultDTO<List<JobInfoDTO>> fetchAllJob();
|
||||
|
||||
ResultDTO<List<JobInfoDTO>> queryJob(JobInfoQuery powerQuery);
|
||||
|
||||
ResultDTO<Void> disableJob(Long jobId);
|
||||
|
||||
ResultDTO<Void> enableJob(Long jobId);
|
||||
|
||||
ResultDTO<Void> deleteJob(Long jobId);
|
||||
|
||||
ResultDTO<Long> runJob(Long jobId, String instanceParams, long delayMS);
|
||||
|
||||
/* ************* Instance API list ************* */
|
||||
|
||||
ResultDTO<Void> stopInstance(Long instanceId);
|
||||
|
||||
ResultDTO<Void> cancelInstance(Long instanceId);
|
||||
|
||||
ResultDTO<Void> retryInstance(Long instanceId);
|
||||
|
||||
ResultDTO<Integer> fetchInstanceStatus(Long instanceId);
|
||||
|
||||
ResultDTO<InstanceInfoDTO> fetchInstanceInfo(Long instanceId);
|
||||
|
||||
ResultDTO<PageResult<InstanceInfoDTO>> queryInstanceInfo(InstancePageQuery instancePageQuery);
|
||||
|
||||
/* ************* Workflow API list ************* */
|
||||
ResultDTO<Long> saveWorkflow(SaveWorkflowRequest request);
|
||||
|
||||
ResultDTO<Long> copyWorkflow(Long workflowId);
|
||||
|
||||
ResultDTO<List<WorkflowNodeInfoDTO>> saveWorkflowNode(List<SaveWorkflowNodeRequest> requestList);
|
||||
|
||||
ResultDTO<WorkflowInfoDTO> fetchWorkflow(Long workflowId);
|
||||
|
||||
ResultDTO<Void> disableWorkflow(Long workflowId);
|
||||
|
||||
ResultDTO<Void> enableWorkflow(Long workflowId);
|
||||
|
||||
ResultDTO<Void> deleteWorkflow(Long workflowId);
|
||||
|
||||
ResultDTO<Long> runWorkflow(Long workflowId, String initParams, long delayMS);
|
||||
|
||||
/* ************* Workflow Instance API list ************* */
|
||||
|
||||
ResultDTO<Void> stopWorkflowInstance(Long wfInstanceId);
|
||||
|
||||
ResultDTO<Void> retryWorkflowInstance(Long wfInstanceId);
|
||||
|
||||
ResultDTO<Void> markWorkflowNodeAsSuccess(Long wfInstanceId, Long nodeId);
|
||||
|
||||
ResultDTO<WorkflowInstanceInfoDTO> fetchWorkflowInstanceInfo(Long wfInstanceId);
|
||||
}
|
@ -0,0 +1,563 @@
|
||||
package tech.powerjob.client;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import tech.powerjob.client.module.AppAuthRequest;
|
||||
import tech.powerjob.client.module.AppAuthResult;
|
||||
import tech.powerjob.client.service.PowerRequestBody;
|
||||
import tech.powerjob.client.service.RequestService;
|
||||
import tech.powerjob.client.service.impl.ClusterRequestServiceOkHttp3Impl;
|
||||
import tech.powerjob.common.OpenAPIConstant;
|
||||
import tech.powerjob.common.enums.EncryptType;
|
||||
import tech.powerjob.common.enums.InstanceStatus;
|
||||
import tech.powerjob.common.exception.PowerJobException;
|
||||
import tech.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import tech.powerjob.common.request.http.SaveWorkflowNodeRequest;
|
||||
import tech.powerjob.common.request.http.SaveWorkflowRequest;
|
||||
import tech.powerjob.common.request.query.InstancePageQuery;
|
||||
import tech.powerjob.common.request.query.JobInfoQuery;
|
||||
import tech.powerjob.common.response.*;
|
||||
import tech.powerjob.common.serialize.JsonUtils;
|
||||
import tech.powerjob.common.utils.CommonUtils;
|
||||
import tech.powerjob.common.utils.DigestUtils;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static tech.powerjob.client.TypeStore.*;
|
||||
|
||||
/**
|
||||
* PowerJobClient, the client for OpenAPI.
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/15
|
||||
*/
|
||||
@Slf4j
|
||||
public class PowerJobClient implements IPowerJobClient, Closeable {
|
||||
|
||||
private Long appId;
|
||||
|
||||
private final RequestService requestService;
|
||||
|
||||
public PowerJobClient(ClientConfig config) {
|
||||
|
||||
List<String> addressList = config.getAddressList();
|
||||
String appName = config.getAppName();
|
||||
|
||||
CommonUtils.requireNonNull(addressList, "addressList can't be null!");
|
||||
CommonUtils.requireNonNull(appName, "appName can't be null");
|
||||
|
||||
this.requestService = new ClusterRequestServiceOkHttp3Impl(config);
|
||||
|
||||
AppAuthRequest appAuthRequest = new AppAuthRequest();
|
||||
appAuthRequest.setAppName(appName);
|
||||
appAuthRequest.setEncryptedPassword(DigestUtils.md5(config.getPassword()));
|
||||
appAuthRequest.setEncryptType(EncryptType.MD5.getCode());
|
||||
|
||||
String assertResponse = requestService.request(OpenAPIConstant.AUTH_APP, PowerRequestBody.newJsonRequestBody(appAuthRequest));
|
||||
|
||||
if (StringUtils.isNotEmpty(assertResponse)) {
|
||||
ResultDTO<AppAuthResult> resultDTO = JSON.parseObject(assertResponse, APP_AUTH_RESULT_TYPE);
|
||||
if (resultDTO.isSuccess()) {
|
||||
appId = resultDTO.getData().getAppId();
|
||||
} else {
|
||||
throw new PowerJobException(resultDTO.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (appId == null) {
|
||||
throw new PowerJobException("appId is null, please check your config");
|
||||
}
|
||||
|
||||
log.info("[PowerJobClient] [INIT] {}'s PowerJobClient bootstrap successfully", appName);
|
||||
}
|
||||
/**
|
||||
* Init PowerJobClient with domain, appName and password.
|
||||
*
|
||||
* @param domain like powerjob-server.apple-inc.com (Intranet Domain)
|
||||
* @param appName name of the application
|
||||
* @param password password of the application
|
||||
*/
|
||||
public PowerJobClient(String domain, String appName, String password) {
|
||||
this(new ClientConfig().setAppName(appName).setPassword(password).setAddressList(Lists.newArrayList(domain)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Init PowerJobClient with server address, appName and password.
|
||||
*
|
||||
* @param addressList IP:Port address list, like 192.168.1.1:7700
|
||||
* @param appName name of the application
|
||||
* @param password password of the application
|
||||
*/
|
||||
public PowerJobClient(List<String> addressList, String appName, String password) {
|
||||
this(new ClientConfig().setAppName(appName).setPassword(password).setAddressList(addressList));
|
||||
}
|
||||
|
||||
/* ************* Job 区 ************* */
|
||||
|
||||
/**
|
||||
* Save one Job
|
||||
* When an ID exists in SaveJobInfoRequest, it is an update operation. Otherwise, it is a crate operation.
|
||||
*
|
||||
* @param request Job meta info
|
||||
* @return jobId
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Long> saveJob(SaveJobInfoRequest request) {
|
||||
|
||||
request.setAppId(appId);
|
||||
String post = requestService.request(OpenAPIConstant.SAVE_JOB, PowerRequestBody.newJsonRequestBody(request));
|
||||
return JSON.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy one Job
|
||||
*
|
||||
* @param jobId Job id
|
||||
* @return Id of job copy
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Long> copyJob(Long jobId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("jobId", jobId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
|
||||
String post = requestService.request(OpenAPIConstant.COPY_JOB, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDTO<SaveJobInfoRequest> exportJob(Long jobId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("jobId", jobId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.EXPORT_JOB, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, SAVE_JOB_INFO_REQUEST_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query JobInfo by jobId
|
||||
*
|
||||
* @param jobId jobId
|
||||
* @return Job meta info
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<JobInfoDTO> fetchJob(Long jobId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("jobId", jobId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.FETCH_JOB, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, JOB_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query all JobInfo
|
||||
*
|
||||
* @return All JobInfo
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<List<JobInfoDTO>> fetchAllJob() {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.FETCH_ALL_JOB, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, LIST_JOB_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query JobInfo by PowerQuery
|
||||
*
|
||||
* @param powerQuery JobQuery
|
||||
* @return JobInfo
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<List<JobInfoDTO>> queryJob(JobInfoQuery powerQuery) {
|
||||
powerQuery.setAppIdEq(appId);
|
||||
String post = requestService.request(OpenAPIConstant.QUERY_JOB, PowerRequestBody.newJsonRequestBody(powerQuery));
|
||||
return JSON.parseObject(post, LIST_JOB_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable one Job by jobId
|
||||
*
|
||||
* @param jobId jobId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> disableJob(Long jobId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("jobId", jobId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.DISABLE_JOB, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable one job by jobId
|
||||
*
|
||||
* @param jobId jobId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> enableJob(Long jobId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("jobId", jobId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.ENABLE_JOB, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one job by jobId
|
||||
*
|
||||
* @param jobId jobId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> deleteJob(Long jobId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("jobId", jobId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.DELETE_JOB, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a job once
|
||||
*
|
||||
* @param jobId ID of the job to be run
|
||||
* @param instanceParams Runtime parameters of the job (TaskContext#instanceParams)
|
||||
* @param delayMS Delay time(Milliseconds)
|
||||
* @return instanceId
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Long> runJob(Long jobId, String instanceParams, long delayMS) {
|
||||
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("jobId", jobId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
param.put("delay", String.valueOf(delayMS));
|
||||
|
||||
if (StringUtils.isNotEmpty(instanceParams)) {
|
||||
param.put("instanceParams", instanceParams);
|
||||
}
|
||||
String post = requestService.request(OpenAPIConstant.RUN_JOB, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
|
||||
public ResultDTO<Long> runJob(Long jobId) {
|
||||
return runJob(jobId, null, 0);
|
||||
}
|
||||
|
||||
/* ************* Instance API list ************* */
|
||||
|
||||
/**
|
||||
* Stop one job instance
|
||||
*
|
||||
* @param instanceId instanceId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> stopInstance(Long instanceId) {
|
||||
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("instanceId", instanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
|
||||
String post = requestService.request(OpenAPIConstant.STOP_INSTANCE, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a job instance that is not yet running
|
||||
* Notice:There is a time interval between the call interface time and the expected execution time of the job instance to be cancelled, otherwise reliability is not guaranteed
|
||||
*
|
||||
* @param instanceId instanceId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> cancelInstance(Long instanceId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("instanceId", instanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.CANCEL_INSTANCE, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry failed job instance
|
||||
* Notice: Only job instance with completion status (success, failure, manually stopped, cancelled) can be retried, and retries of job instances within workflows are not supported yet.
|
||||
*
|
||||
* @param instanceId instanceId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> retryInstance(Long instanceId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("instanceId", instanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.RETRY_INSTANCE, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query status about a job instance
|
||||
*
|
||||
* @param instanceId instanceId
|
||||
* @return {@link InstanceStatus}
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Integer> fetchInstanceStatus(Long instanceId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("instanceId", instanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.FETCH_INSTANCE_STATUS, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, INTEGER_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query detail about a job instance
|
||||
*
|
||||
* @param instanceId instanceId
|
||||
* @return instance detail
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<InstanceInfoDTO> fetchInstanceInfo(Long instanceId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("instanceId", instanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.FETCH_INSTANCE_INFO, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, INSTANCE_RESULT_TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDTO<PageResult<InstanceInfoDTO>> queryInstanceInfo(InstancePageQuery instancePageQuery) {
|
||||
instancePageQuery.setAppIdEq(appId);
|
||||
String post = requestService.request(OpenAPIConstant.QUERY_INSTANCE, PowerRequestBody.newJsonRequestBody(instancePageQuery));
|
||||
return JSON.parseObject(post, PAGE_INSTANCE_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/* ************* Workflow API list ************* */
|
||||
|
||||
/**
|
||||
* Save one workflow
|
||||
* When an ID exists in SaveWorkflowRequest, it is an update operation. Otherwise, it is a crate operation.
|
||||
*
|
||||
* @param request Workflow meta info
|
||||
* @return workflowId
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Long> saveWorkflow(SaveWorkflowRequest request) {
|
||||
request.setAppId(appId);
|
||||
// 中坑记录:用 FastJSON 序列化会导致 Server 接收时 pEWorkflowDAG 为 null,无语.jpg
|
||||
String json = JsonUtils.toJSONStringUnsafe(request);
|
||||
String post = requestService.request(OpenAPIConstant.SAVE_WORKFLOW, PowerRequestBody.newJsonRequestBody(json));
|
||||
return JSON.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy one workflow
|
||||
*
|
||||
* @param workflowId Workflow id
|
||||
* @return Id of workflow copy
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Long> copyWorkflow(Long workflowId) {
|
||||
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("workflowId", workflowId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
|
||||
String post = requestService.request(OpenAPIConstant.COPY_WORKFLOW, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加工作流节点
|
||||
*
|
||||
* @param requestList Node info list of Workflow
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<List<WorkflowNodeInfoDTO>> saveWorkflowNode(List<SaveWorkflowNodeRequest> requestList) {
|
||||
for (SaveWorkflowNodeRequest saveWorkflowNodeRequest : requestList) {
|
||||
saveWorkflowNodeRequest.setAppId(appId);
|
||||
}
|
||||
|
||||
String json = JsonUtils.toJSONStringUnsafe(requestList);
|
||||
String post = requestService.request(OpenAPIConstant.SAVE_WORKFLOW_NODE, PowerRequestBody.newJsonRequestBody(json));
|
||||
return JSON.parseObject(post, WF_NODE_LIST_RESULT_TYPE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Query Workflow by workflowId
|
||||
*
|
||||
* @param workflowId workflowId
|
||||
* @return Workflow meta info
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<WorkflowInfoDTO> fetchWorkflow(Long workflowId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("workflowId", workflowId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.FETCH_WORKFLOW, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, WF_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable Workflow by workflowId
|
||||
*
|
||||
* @param workflowId workflowId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> disableWorkflow(Long workflowId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("workflowId", workflowId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.DISABLE_WORKFLOW, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable Workflow by workflowId
|
||||
*
|
||||
* @param workflowId workflowId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> enableWorkflow(Long workflowId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("workflowId", workflowId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.ENABLE_WORKFLOW, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Workflow by workflowId
|
||||
*
|
||||
* @param workflowId workflowId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> deleteWorkflow(Long workflowId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("workflowId", workflowId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.DELETE_WORKFLOW, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a workflow once
|
||||
*
|
||||
* @param workflowId workflowId
|
||||
* @param initParams workflow startup parameters
|
||||
* @param delayMS Delay time(Milliseconds)
|
||||
* @return workflow instanceId
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Long> runWorkflow(Long workflowId, String initParams, long delayMS) {
|
||||
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("workflowId", workflowId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
param.put("delay", String.valueOf(delayMS));
|
||||
|
||||
|
||||
if (StringUtils.isNotEmpty(initParams)) {
|
||||
param.put("initParams", initParams);
|
||||
}
|
||||
String post = requestService.request(OpenAPIConstant.RUN_WORKFLOW, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, LONG_RESULT_TYPE);
|
||||
}
|
||||
|
||||
public ResultDTO<Long> runWorkflow(Long workflowId) {
|
||||
return runWorkflow(workflowId, null, 0);
|
||||
}
|
||||
|
||||
/* ************* Workflow Instance API list ************* */
|
||||
|
||||
/**
|
||||
* Stop one workflow instance
|
||||
*
|
||||
* @param wfInstanceId workflow instanceId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> stopWorkflowInstance(Long wfInstanceId) {
|
||||
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("wfInstanceId", wfInstanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
|
||||
String post = requestService.request(OpenAPIConstant.STOP_WORKFLOW_INSTANCE, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry one workflow instance
|
||||
*
|
||||
* @param wfInstanceId workflow instanceId
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> retryWorkflowInstance(Long wfInstanceId) {
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("wfInstanceId", wfInstanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
String post = requestService.request(OpenAPIConstant.RETRY_WORKFLOW_INSTANCE, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* mark the workflow node as success
|
||||
*
|
||||
* @param wfInstanceId workflow instanceId
|
||||
* @param nodeId node id
|
||||
* @return Standard return object
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<Void> markWorkflowNodeAsSuccess(Long wfInstanceId, Long nodeId) {
|
||||
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("wfInstanceId", wfInstanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
param.put("nodeId", nodeId.toString());
|
||||
|
||||
String post = requestService.request(OpenAPIConstant.MARK_WORKFLOW_NODE_AS_SUCCESS, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, VOID_RESULT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query detail about a workflow instance
|
||||
*
|
||||
* @param wfInstanceId workflow instanceId
|
||||
* @return detail about a workflow
|
||||
*/
|
||||
@Override
|
||||
public ResultDTO<WorkflowInstanceInfoDTO> fetchWorkflowInstanceInfo(Long wfInstanceId) {
|
||||
|
||||
Map<String, String> param = Maps.newHashMap();
|
||||
param.put("wfInstanceId", wfInstanceId.toString());
|
||||
param.put("appId", appId.toString());
|
||||
|
||||
String post = requestService.request(OpenAPIConstant.FETCH_WORKFLOW_INSTANCE_INFO, PowerRequestBody.newFormRequestBody(param));
|
||||
return JSON.parseObject(post, WF_INSTANCE_RESULT_TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
requestService.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package tech.powerjob.client;
|
||||
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import tech.powerjob.client.module.AppAuthResult;
|
||||
import tech.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import tech.powerjob.common.response.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TypeReference store.
|
||||
*
|
||||
* @author tjq
|
||||
* @since 11/7/20
|
||||
*/
|
||||
public class TypeStore {
|
||||
|
||||
public static final TypeReference<ResultDTO<AppAuthResult>> APP_AUTH_RESULT_TYPE = new TypeReference<ResultDTO<AppAuthResult>>(){};
|
||||
public static final TypeReference<ResultDTO<Void>> VOID_RESULT_TYPE = new TypeReference<ResultDTO<Void>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<Integer>> INTEGER_RESULT_TYPE = new TypeReference<ResultDTO<Integer>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<Long>> LONG_RESULT_TYPE = new TypeReference<ResultDTO<Long>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<JobInfoDTO>> JOB_RESULT_TYPE = new TypeReference<ResultDTO<JobInfoDTO>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<SaveJobInfoRequest>> SAVE_JOB_INFO_REQUEST_RESULT_TYPE = new TypeReference<ResultDTO<SaveJobInfoRequest>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<List<JobInfoDTO>>> LIST_JOB_RESULT_TYPE = new TypeReference<ResultDTO<List<JobInfoDTO>>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<InstanceInfoDTO>> INSTANCE_RESULT_TYPE = new TypeReference<ResultDTO<InstanceInfoDTO>>() {};
|
||||
|
||||
public static final TypeReference<ResultDTO<List<InstanceInfoDTO>>> LIST_INSTANCE_RESULT_TYPE = new TypeReference<ResultDTO<List<InstanceInfoDTO>>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<PageResult<InstanceInfoDTO>>> PAGE_INSTANCE_RESULT_TYPE = new TypeReference<ResultDTO<PageResult<InstanceInfoDTO>>>(){};
|
||||
|
||||
public static final TypeReference<ResultDTO<WorkflowInfoDTO>> WF_RESULT_TYPE = new TypeReference<ResultDTO<WorkflowInfoDTO>>() {};
|
||||
|
||||
public static final TypeReference<ResultDTO<WorkflowInstanceInfoDTO>> WF_INSTANCE_RESULT_TYPE = new TypeReference<ResultDTO<WorkflowInstanceInfoDTO>>() {};
|
||||
|
||||
public static final TypeReference<ResultDTO<List<WorkflowNodeInfoDTO>>> WF_NODE_LIST_RESULT_TYPE = new TypeReference<ResultDTO<List<WorkflowNodeInfoDTO>>> () {};
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package tech.powerjob.client.common;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Protocol
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
@Getter
|
||||
public enum Protocol {
|
||||
|
||||
HTTP("http"),
|
||||
|
||||
HTTPS("https");
|
||||
|
||||
private final String protocol;
|
||||
|
||||
Protocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return protocol;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package tech.powerjob.client.extension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 扩展服务
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/8/11
|
||||
*/
|
||||
public interface ClientExtension {
|
||||
|
||||
/**
|
||||
* 动态提供地址,适用于 server 部署在动态集群上的场景
|
||||
* @param context 上下文
|
||||
* @return 地址,格式要求同 ClientConfig#addressList
|
||||
*/
|
||||
List<String> addressProvider(ExtensionContext context);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package tech.powerjob.client.extension;
|
||||
|
||||
/**
|
||||
* 扩展上下文
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/8/11
|
||||
*/
|
||||
public class ExtensionContext {
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package tech.powerjob.client.module;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* App 鉴权请求
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/2/19
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class AppAuthRequest implements Serializable {
|
||||
|
||||
/**
|
||||
* 应用名称
|
||||
*/
|
||||
private String appName;
|
||||
/**
|
||||
* 加密后密码
|
||||
*/
|
||||
private String encryptedPassword;
|
||||
|
||||
/**
|
||||
* 加密类型
|
||||
*/
|
||||
private String encryptType;
|
||||
|
||||
/**
|
||||
* 额外参数,方便开发者传递其他参数
|
||||
*/
|
||||
private Map<String, Object> extra;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package tech.powerjob.client.module;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* App 鉴权响应
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/2/21
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class AppAuthResult implements Serializable {
|
||||
|
||||
private Long appId;
|
||||
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* 额外参数
|
||||
* 有安全需求的开发者可执行扩展
|
||||
*/
|
||||
private Map<String, Object> extra;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package tech.powerjob.client.service;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* HTTP 响应
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/8/10
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class HttpResponse implements Serializable {
|
||||
|
||||
private boolean success;
|
||||
|
||||
private int code;
|
||||
|
||||
private String response;
|
||||
|
||||
private Map<String, String> headers;
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package tech.powerjob.client.service;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.Getter;
|
||||
import tech.powerjob.common.enums.MIME;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 请求体
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/8/10
|
||||
*/
|
||||
@Getter
|
||||
public class PowerRequestBody {
|
||||
|
||||
private MIME mime;
|
||||
|
||||
private Object payload;
|
||||
|
||||
private final Map<String, String> headers = Maps.newHashMap();
|
||||
|
||||
private PowerRequestBody() {
|
||||
}
|
||||
|
||||
public static PowerRequestBody newJsonRequestBody(Object data) {
|
||||
PowerRequestBody powerRequestBody = new PowerRequestBody();
|
||||
powerRequestBody.mime = MIME.APPLICATION_JSON;
|
||||
powerRequestBody.payload = data;
|
||||
return powerRequestBody;
|
||||
}
|
||||
|
||||
public static PowerRequestBody newFormRequestBody(Map<String, String> form) {
|
||||
PowerRequestBody powerRequestBody = new PowerRequestBody();
|
||||
powerRequestBody.mime = MIME.APPLICATION_FORM;
|
||||
powerRequestBody.payload = form;
|
||||
return powerRequestBody;
|
||||
}
|
||||
|
||||
public void addHeaders(Map<String, String> hs) {
|
||||
if (hs == null || hs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
this.headers.putAll(hs);
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package tech.powerjob.client.service;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
/**
|
||||
* 请求服务
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
public interface RequestService extends Closeable {
|
||||
|
||||
|
||||
String request(String path, PowerRequestBody powerRequestBody);
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package tech.powerjob.client.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.powerjob.client.ClientConfig;
|
||||
import tech.powerjob.client.TypeStore;
|
||||
import tech.powerjob.client.module.AppAuthRequest;
|
||||
import tech.powerjob.client.module.AppAuthResult;
|
||||
import tech.powerjob.client.service.HttpResponse;
|
||||
import tech.powerjob.client.service.PowerRequestBody;
|
||||
import tech.powerjob.common.OpenAPIConstant;
|
||||
import tech.powerjob.common.enums.EncryptType;
|
||||
import tech.powerjob.common.exception.PowerJobException;
|
||||
import tech.powerjob.common.response.ResultDTO;
|
||||
import tech.powerjob.common.utils.DigestUtils;
|
||||
import tech.powerjob.common.utils.MapUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 封装鉴权相关逻辑
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/2/21
|
||||
*/
|
||||
@Slf4j
|
||||
abstract class AppAuthClusterRequestService extends ClusterRequestService {
|
||||
|
||||
protected AppAuthResult appAuthResult;
|
||||
|
||||
public AppAuthClusterRequestService(ClientConfig config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String request(String path, PowerRequestBody powerRequestBody) {
|
||||
// 若不存在 appAuthResult,则首先进行鉴权
|
||||
if (appAuthResult == null) {
|
||||
refreshAppAuthResult();
|
||||
}
|
||||
|
||||
HttpResponse httpResponse = doRequest(path, powerRequestBody);
|
||||
|
||||
// 如果 auth 成功,则代表请求有效,直接返回
|
||||
String authStatus = MapUtils.getString(httpResponse.getHeaders(), OpenAPIConstant.RESPONSE_HEADER_AUTH_STATUS);
|
||||
if (Boolean.TRUE.toString().equalsIgnoreCase(authStatus)) {
|
||||
return httpResponse.getResponse();
|
||||
}
|
||||
|
||||
// 否则请求无效,刷新鉴权后重新请求
|
||||
log.warn("[PowerJobClient] auth failed[authStatus: {}], try to refresh the auth info", authStatus);
|
||||
refreshAppAuthResult();
|
||||
httpResponse = doRequest(path, powerRequestBody);
|
||||
|
||||
// 只要请求不失败,直接返回(如果鉴权失败则返回鉴权错误信息,server 保证 response 永远非空)
|
||||
return httpResponse.getResponse();
|
||||
}
|
||||
|
||||
private HttpResponse doRequest(String path, PowerRequestBody powerRequestBody) {
|
||||
|
||||
// 添加鉴权信息
|
||||
Map<String, String> authHeaders = buildAuthHeader();
|
||||
powerRequestBody.addHeaders(authHeaders);
|
||||
|
||||
HttpResponse httpResponse = clusterHaRequest(path, powerRequestBody);
|
||||
|
||||
// 任何请求不成功,都直接报错
|
||||
if (!httpResponse.isSuccess()) {
|
||||
throw new PowerJobException("REMOTE_SERVER_INNER_EXCEPTION");
|
||||
}
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
private Map<String, String> buildAuthHeader() {
|
||||
Map<String, String> authHeader = Maps.newHashMap();
|
||||
authHeader.put(OpenAPIConstant.REQUEST_HEADER_APP_ID, String.valueOf(appAuthResult.getAppId()));
|
||||
authHeader.put(OpenAPIConstant.REQUEST_HEADER_ACCESS_TOKEN, appAuthResult.getToken());
|
||||
return authHeader;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void refreshAppAuthResult() {
|
||||
AppAuthRequest appAuthRequest = buildAppAuthRequest();
|
||||
HttpResponse httpResponse = clusterHaRequest(OpenAPIConstant.AUTH_APP, PowerRequestBody.newJsonRequestBody(appAuthRequest));
|
||||
if (!httpResponse.isSuccess()) {
|
||||
throw new PowerJobException("AUTH_APP_EXCEPTION!");
|
||||
}
|
||||
ResultDTO<AppAuthResult> authResultDTO = JSONObject.parseObject(httpResponse.getResponse(), TypeStore.APP_AUTH_RESULT_TYPE);
|
||||
if (!authResultDTO.isSuccess()) {
|
||||
throw new PowerJobException("AUTH_FAILED_" + authResultDTO.getMessage());
|
||||
}
|
||||
|
||||
log.warn("[PowerJobClient] refresh auth info successfully!");
|
||||
this.appAuthResult = authResultDTO.getData();
|
||||
}
|
||||
|
||||
protected AppAuthRequest buildAppAuthRequest() {
|
||||
AppAuthRequest appAuthRequest = new AppAuthRequest();
|
||||
appAuthRequest.setAppName(config.getAppName());
|
||||
appAuthRequest.setEncryptedPassword(DigestUtils.md5(config.getPassword()));
|
||||
appAuthRequest.setEncryptType(EncryptType.MD5.getCode());
|
||||
return appAuthRequest;
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package tech.powerjob.client.service.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import tech.powerjob.client.ClientConfig;
|
||||
import tech.powerjob.client.extension.ClientExtension;
|
||||
import tech.powerjob.client.extension.ExtensionContext;
|
||||
import tech.powerjob.client.service.HttpResponse;
|
||||
import tech.powerjob.client.service.PowerRequestBody;
|
||||
import tech.powerjob.client.service.RequestService;
|
||||
import tech.powerjob.common.OpenAPIConstant;
|
||||
import tech.powerjob.common.exception.PowerJobException;
|
||||
import tech.powerjob.common.utils.CollectionUtils;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.io.IOException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 集群请求服务
|
||||
* 封装网络相关通用逻辑
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/2/21
|
||||
*/
|
||||
@Slf4j
|
||||
abstract class ClusterRequestService implements RequestService {
|
||||
|
||||
protected final ClientConfig config;
|
||||
|
||||
/**
|
||||
* 当前地址(上次请求成功的地址)
|
||||
*/
|
||||
protected String currentAddress;
|
||||
|
||||
/**
|
||||
* 地址格式
|
||||
* 协议://域名/OpenAPI/子路径
|
||||
*/
|
||||
protected static final String URL_PATTERN = "%s://%s%s%s";
|
||||
|
||||
/**
|
||||
* 默认超时时间
|
||||
*/
|
||||
protected static final Integer DEFAULT_TIMEOUT_SECONDS = 2;
|
||||
|
||||
protected static final int HTTP_SUCCESS_CODE = 200;
|
||||
|
||||
public ClusterRequestService(ClientConfig config) {
|
||||
this.config = config;
|
||||
this.currentAddress = config.getAddressList().get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 具体某一次 HTTP 请求的实现
|
||||
* @param url 完整请求地址
|
||||
* @param body 请求体
|
||||
* @return 响应
|
||||
* @throws IOException 异常
|
||||
*/
|
||||
protected abstract HttpResponse sendHttpRequest(String url, PowerRequestBody body) throws IOException;
|
||||
|
||||
/**
|
||||
* 封装集群请求能力
|
||||
* @param path 请求 PATH
|
||||
* @param powerRequestBody 请求体
|
||||
* @return 响应
|
||||
*/
|
||||
protected HttpResponse clusterHaRequest(String path, PowerRequestBody powerRequestBody) {
|
||||
|
||||
// 先尝试默认地址
|
||||
String url = getUrl(path, currentAddress);
|
||||
try {
|
||||
return sendHttpRequest(url, powerRequestBody);
|
||||
} catch (IOException e) {
|
||||
log.warn("[ClusterRequestService] request url:{} failed, reason is {}.", url, e.toString());
|
||||
}
|
||||
|
||||
List<String> addressList = fetchAddressList();
|
||||
|
||||
// 失败,开始重试
|
||||
for (String addr : addressList) {
|
||||
if (Objects.equals(addr, currentAddress)) {
|
||||
continue;
|
||||
}
|
||||
url = getUrl(path, addr);
|
||||
try {
|
||||
HttpResponse res = sendHttpRequest(url, powerRequestBody);
|
||||
log.warn("[ClusterRequestService] server change: from({}) -> to({}).", currentAddress, addr);
|
||||
currentAddress = addr;
|
||||
return res;
|
||||
} catch (IOException e) {
|
||||
log.warn("[ClusterRequestService] request url:{} failed, reason is {}.", url, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
log.error("[ClusterRequestService] do post for path: {} failed because of no server available in {}.", path, addressList);
|
||||
throw new PowerJobException("no server available when send post request");
|
||||
}
|
||||
|
||||
private List<String> fetchAddressList() {
|
||||
|
||||
ClientExtension clientExtension = config.getClientExtension();
|
||||
if (clientExtension != null) {
|
||||
List<String> addressList = clientExtension.addressProvider(new ExtensionContext());
|
||||
if (!CollectionUtils.isEmpty(addressList)) {
|
||||
return addressList;
|
||||
}
|
||||
}
|
||||
|
||||
return config.getAddressList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 不验证证书
|
||||
* X.509 是一个国际标准,定义了公钥证书的格式。这个标准是由国际电信联盟(ITU-T)制定的,用于公钥基础设施(PKI)中数字证书的创建和分发。X.509证书主要用于在公开网络上验证实体的身份,如服务器或客户端的身份验证过程中,确保通信双方是可信的。X.509证书广泛应用于多种安全协议中,包括SSL/TLS,它是实现HTTPS的基础。
|
||||
*/
|
||||
protected static class NoVerifyX509TrustManager implements X509TrustManager {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
|
||||
// 不验证
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String getUrl(String path, String address) {
|
||||
String protocol = config.getProtocol().getProtocol();
|
||||
return String.format(URL_PATTERN, protocol, address, OpenAPIConstant.WEB_PATH, path);
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
package tech.powerjob.client.service.impl;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.*;
|
||||
import tech.powerjob.client.ClientConfig;
|
||||
import tech.powerjob.client.common.Protocol;
|
||||
import tech.powerjob.client.service.HttpResponse;
|
||||
import tech.powerjob.client.service.PowerRequestBody;
|
||||
import tech.powerjob.common.OmsConstant;
|
||||
import tech.powerjob.common.serialize.JsonUtils;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* desc
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
@Slf4j
|
||||
public class ClusterRequestServiceOkHttp3Impl extends AppAuthClusterRequestService {
|
||||
|
||||
private final OkHttpClient okHttpClient;
|
||||
|
||||
|
||||
public ClusterRequestServiceOkHttp3Impl(ClientConfig config) {
|
||||
super(config);
|
||||
|
||||
// 初始化 HTTP 客户端
|
||||
if (Protocol.HTTPS.equals(config.getProtocol())) {
|
||||
okHttpClient = initHttpsNoVerifyClient();
|
||||
} else {
|
||||
okHttpClient = initHttpClient();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpResponse sendHttpRequest(String url, PowerRequestBody powerRequestBody) throws IOException {
|
||||
|
||||
// 添加公共 header
|
||||
powerRequestBody.addHeaders(config.getDefaultHeaders());
|
||||
|
||||
Object obj = powerRequestBody.getPayload();
|
||||
|
||||
RequestBody requestBody = null;
|
||||
|
||||
switch (powerRequestBody.getMime()) {
|
||||
case APPLICATION_JSON:
|
||||
MediaType jsonType = MediaType.parse(OmsConstant.JSON_MEDIA_TYPE);
|
||||
String body = obj instanceof String ? (String) obj : JsonUtils.toJSONStringUnsafe(obj);
|
||||
requestBody = RequestBody.create(jsonType, body);
|
||||
|
||||
break;
|
||||
case APPLICATION_FORM:
|
||||
FormBody.Builder formBuilder = new FormBody.Builder();
|
||||
Map<String, String> formObj = (Map<String, String>) obj;
|
||||
formObj.forEach(formBuilder::add);
|
||||
requestBody = formBuilder.build();
|
||||
}
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(requestBody)
|
||||
.headers(Headers.of(powerRequestBody.getHeaders()))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = okHttpClient.newCall(request).execute()) {
|
||||
|
||||
int code = response.code();
|
||||
HttpResponse httpResponse = new HttpResponse()
|
||||
.setCode(code)
|
||||
.setSuccess(code == HTTP_SUCCESS_CODE);
|
||||
|
||||
ResponseBody body = response.body();
|
||||
if (body != null) {
|
||||
httpResponse.setResponse(body.string());
|
||||
}
|
||||
|
||||
Headers respHeaders = response.headers();
|
||||
Set<String> headerNames = respHeaders.names();
|
||||
Map<String, String> respHeaderMap = Maps.newHashMap();
|
||||
headerNames.forEach(hdKey -> respHeaderMap.put(hdKey, respHeaders.get(hdKey)));
|
||||
|
||||
httpResponse.setHeaders(respHeaderMap);
|
||||
|
||||
return httpResponse;
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private OkHttpClient initHttpClient() {
|
||||
OkHttpClient.Builder okHttpBuilder = commonOkHttpBuilder();
|
||||
return okHttpBuilder.build();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private OkHttpClient initHttpsNoVerifyClient() {
|
||||
|
||||
X509TrustManager trustManager = new NoVerifyX509TrustManager();
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, new TrustManager[]{trustManager}, new SecureRandom());
|
||||
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||
|
||||
OkHttpClient.Builder okHttpBuilder = commonOkHttpBuilder();
|
||||
|
||||
// 不需要校验证书
|
||||
okHttpBuilder.sslSocketFactory(sslSocketFactory, trustManager);
|
||||
// 不校验 url中的 hostname
|
||||
okHttpBuilder.hostnameVerifier((String hostname, SSLSession session) -> true);
|
||||
|
||||
|
||||
return okHttpBuilder.build();
|
||||
}
|
||||
|
||||
private OkHttpClient.Builder commonOkHttpBuilder() {
|
||||
return new OkHttpClient.Builder()
|
||||
// 设置读取超时时间
|
||||
.readTimeout(Optional.ofNullable(config.getReadTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS)
|
||||
// 设置写的超时时间
|
||||
.writeTimeout(Optional.ofNullable(config.getWriteTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS)
|
||||
// 设置连接超时时间
|
||||
.connectTimeout(Optional.ofNullable(config.getConnectionTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS)
|
||||
.callTimeout(Optional.ofNullable(config.getConnectionTimeout()).orElse(DEFAULT_TIMEOUT_SECONDS), TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
||||
// 关闭 Dispatcher
|
||||
okHttpClient.dispatcher().executorService().shutdown();
|
||||
// 清理连接池
|
||||
okHttpClient.connectionPool().evictAll();
|
||||
// 清理缓存(如果有使用)
|
||||
Cache cache = okHttpClient.cache();
|
||||
if (cache != null) {
|
||||
cache.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.kfcfans.powerjob.common.ExecuteType;
|
||||
import com.github.kfcfans.powerjob.common.ProcessorType;
|
||||
import com.github.kfcfans.powerjob.common.TimeExpressionType;
|
||||
import com.github.kfcfans.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import com.github.kfcfans.powerjob.common.response.JobInfoDTO;
|
||||
import com.github.kfcfans.powerjob.common.response.ResultDTO;
|
||||
import com.github.kfcfans.powerjob.client.OhMyClient;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 测试 Client
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/15
|
||||
*/
|
||||
public class TestClient {
|
||||
|
||||
private static OhMyClient ohMyClient;
|
||||
|
||||
public static final long JOB_ID = 4L;
|
||||
|
||||
@BeforeAll
|
||||
public static void initClient() throws Exception {
|
||||
ohMyClient = new OhMyClient("127.0.0.1:7700", "powerjob-agent-test", "123");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveJob() throws Exception {
|
||||
|
||||
SaveJobInfoRequest newJobInfo = new SaveJobInfoRequest();
|
||||
newJobInfo.setId(JOB_ID);
|
||||
newJobInfo.setJobName("omsOpenAPIJobccccc");
|
||||
newJobInfo.setJobDescription("tes OpenAPI");
|
||||
newJobInfo.setJobParams("{'aa':'bb'}");
|
||||
newJobInfo.setTimeExpressionType(TimeExpressionType.CRON);
|
||||
newJobInfo.setTimeExpression("0 0 * * * ? ");
|
||||
newJobInfo.setExecuteType(ExecuteType.STANDALONE);
|
||||
newJobInfo.setProcessorType(ProcessorType.EMBEDDED_JAVA);
|
||||
newJobInfo.setProcessorInfo("com.github.kfcfans.powerjob.samples.processors.StandaloneProcessorDemo");
|
||||
newJobInfo.setDesignatedWorkers("");
|
||||
|
||||
newJobInfo.setMinCpuCores(1.1);
|
||||
newJobInfo.setMinMemorySpace(1.2);
|
||||
newJobInfo.setMinDiskSpace(1.3);
|
||||
|
||||
ResultDTO<Long> resultDTO = ohMyClient.saveJob(newJobInfo);
|
||||
System.out.println(JSONObject.toJSONString(resultDTO));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchJob() throws Exception {
|
||||
ResultDTO<JobInfoDTO> fetchJob = ohMyClient.fetchJob(JOB_ID);
|
||||
System.out.println(JSONObject.toJSONString(fetchJob));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableJob() throws Exception {
|
||||
System.out.println(ohMyClient.disableJob(JOB_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableJob() throws Exception {
|
||||
System.out.println(ohMyClient.enableJob(JOB_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteJob() throws Exception {
|
||||
System.out.println(ohMyClient.deleteJob(JOB_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun() {
|
||||
System.out.println(ohMyClient.runJob(JOB_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunJobDelay() throws Exception {
|
||||
System.out.println(ohMyClient.runJob(JOB_ID, "this is instanceParams", 60000));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchInstanceInfo() throws Exception {
|
||||
System.out.println(ohMyClient.fetchInstanceInfo(205436386851946560L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopInstance() throws Exception {
|
||||
ResultDTO<Void> res = ohMyClient.stopInstance(205436995885858880L);
|
||||
System.out.println(res.toString());
|
||||
}
|
||||
@Test
|
||||
public void testFetchInstanceStatus() throws Exception {
|
||||
System.out.println(ohMyClient.fetchInstanceStatus(205436995885858880L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelInstanceInTimeWheel() throws Exception {
|
||||
ResultDTO<Long> startRes = ohMyClient.runJob(JOB_ID, "start by OhMyClient", 20000);
|
||||
System.out.println("runJob result: " + JSONObject.toJSONString(startRes));
|
||||
ResultDTO<Void> cancelRes = ohMyClient.cancelInstance(startRes.getData());
|
||||
System.out.println("cancelJob result: " + JSONObject.toJSONString(cancelRes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelInstanceInDatabase() throws Exception {
|
||||
ResultDTO<Long> startRes = ohMyClient.runJob(15L, "start by OhMyClient", 2000000);
|
||||
System.out.println("runJob result: " + JSONObject.toJSONString(startRes));
|
||||
|
||||
// 手动重启 server,干掉时间轮中的调度数据
|
||||
TimeUnit.MINUTES.sleep(1);
|
||||
|
||||
ResultDTO<Void> cancelRes = ohMyClient.cancelInstance(startRes.getData());
|
||||
System.out.println("cancelJob result: " + JSONObject.toJSONString(cancelRes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetryInstance() throws Exception {
|
||||
ResultDTO<Void> res = ohMyClient.retryInstance(169557545206153344L);
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.kfcfans.powerjob.client.OhMyClient;
|
||||
import com.github.kfcfans.powerjob.common.ExecuteType;
|
||||
import com.github.kfcfans.powerjob.common.ProcessorType;
|
||||
import com.github.kfcfans.powerjob.common.TimeExpressionType;
|
||||
import com.github.kfcfans.powerjob.common.model.PEWorkflowDAG;
|
||||
import com.github.kfcfans.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import com.github.kfcfans.powerjob.common.request.http.SaveWorkflowRequest;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 测试 Client(workflow部分)
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/6/2
|
||||
*/
|
||||
public class TestWorkflow {
|
||||
|
||||
private static OhMyClient ohMyClient;
|
||||
|
||||
private static final long WF_ID = 1;
|
||||
|
||||
@BeforeAll
|
||||
public static void initClient() throws Exception {
|
||||
ohMyClient = new OhMyClient("127.0.0.1:7700", "powerjob-agent-test", "123");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initTestData() throws Exception {
|
||||
SaveJobInfoRequest base = new SaveJobInfoRequest();
|
||||
base.setJobName("DAG-Node-");
|
||||
base.setTimeExpressionType(TimeExpressionType.WORKFLOW);
|
||||
base.setExecuteType(ExecuteType.STANDALONE);
|
||||
base.setProcessorType(ProcessorType.EMBEDDED_JAVA);
|
||||
base.setProcessorInfo("com.github.kfcfans.powerjob.samples.workflow.WorkflowStandaloneProcessor");
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
SaveJobInfoRequest request = JSONObject.parseObject(JSONObject.toJSONBytes(base), SaveJobInfoRequest.class);
|
||||
request.setJobName(request.getJobName() + i);
|
||||
System.out.println(ohMyClient.saveJob(request));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveWorkflow() throws Exception {
|
||||
|
||||
// DAG 图
|
||||
List<PEWorkflowDAG.Node> nodes = Lists.newLinkedList();
|
||||
List<PEWorkflowDAG.Edge> edges = Lists.newLinkedList();
|
||||
|
||||
nodes.add(new PEWorkflowDAG.Node(1L, "DAG-Node-1"));
|
||||
nodes.add(new PEWorkflowDAG.Node(2L, "DAG-Node-2"));
|
||||
|
||||
edges.add(new PEWorkflowDAG.Edge(1L, 2L));
|
||||
|
||||
PEWorkflowDAG peWorkflowDAG = new PEWorkflowDAG(nodes, edges);
|
||||
SaveWorkflowRequest req = new SaveWorkflowRequest();
|
||||
|
||||
req.setWfName("workflow-by-client");
|
||||
req.setWfDescription("created by client");
|
||||
req.setPEWorkflowDAG(peWorkflowDAG);
|
||||
req.setEnable(true);
|
||||
req.setTimeExpressionType(TimeExpressionType.API);
|
||||
|
||||
System.out.println("req ->" + JSONObject.toJSON(req));
|
||||
System.out.println(ohMyClient.saveWorkflow(req));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableWorkflow() throws Exception {
|
||||
System.out.println(ohMyClient.disableWorkflow(WF_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteWorkflow() throws Exception {
|
||||
System.out.println(ohMyClient.deleteWorkflow(WF_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableWorkflow() throws Exception {
|
||||
System.out.println(ohMyClient.enableWorkflow(WF_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchWorkflowInfo() throws Exception {
|
||||
System.out.println(ohMyClient.fetchWorkflow(WF_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunWorkflow() throws Exception {
|
||||
System.out.println(ohMyClient.runWorkflow(WF_ID));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopWorkflowInstance() throws Exception {
|
||||
System.out.println(ohMyClient.stopWorkflowInstance(149962433421639744L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchWfInstanceInfo() throws Exception {
|
||||
System.out.println(ohMyClient.fetchWorkflowInstanceInfo(149962433421639744L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRunWorkflowPlus() throws Exception {
|
||||
System.out.println(ohMyClient.runWorkflow(WF_ID, "this is init Params 2", 90000));
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import tech.powerjob.client.IPowerJobClient;
|
||||
import tech.powerjob.client.PowerJobClient;
|
||||
|
||||
/**
|
||||
* Initialize OhMyClient
|
||||
*
|
||||
* @author tjq
|
||||
* @since 1/16/21
|
||||
*/
|
||||
public class ClientInitializer {
|
||||
|
||||
protected static IPowerJobClient powerJobClient;
|
||||
|
||||
@BeforeAll
|
||||
public static void initClient() throws Exception {
|
||||
powerJobClient = new PowerJobClient(Lists.newArrayList("127.0.0.1:7700", "127.0.0.1:7701"), "powerjob-worker-samples", "powerjob123");
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import tech.powerjob.client.PowerJobClient;
|
||||
import tech.powerjob.common.enums.ExecuteType;
|
||||
import tech.powerjob.common.enums.ProcessorType;
|
||||
import tech.powerjob.common.enums.TimeExpressionType;
|
||||
import tech.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import tech.powerjob.common.request.query.InstancePageQuery;
|
||||
import tech.powerjob.common.response.InstanceInfoDTO;
|
||||
import tech.powerjob.common.response.JobInfoDTO;
|
||||
import tech.powerjob.common.response.ResultDTO;
|
||||
|
||||
/**
|
||||
* Test cases for {@link PowerJobClient}
|
||||
*
|
||||
* @author tjq
|
||||
* @author Echo009
|
||||
* @since 2020/4/15
|
||||
*/
|
||||
@Slf4j
|
||||
class TestClient extends ClientInitializer {
|
||||
|
||||
public static final long JOB_ID = 1L;
|
||||
|
||||
@Test
|
||||
void testSaveJob() {
|
||||
|
||||
SaveJobInfoRequest newJobInfo = new SaveJobInfoRequest();
|
||||
newJobInfo.setId(JOB_ID);
|
||||
newJobInfo.setJobName("omsOpenAPIJobccccc" + System.currentTimeMillis());
|
||||
newJobInfo.setJobDescription("test OpenAPI" + System.currentTimeMillis());
|
||||
newJobInfo.setJobParams("{'aa':'bb'}");
|
||||
newJobInfo.setTimeExpressionType(TimeExpressionType.CRON);
|
||||
newJobInfo.setTimeExpression("0 0 * * * ? ");
|
||||
newJobInfo.setExecuteType(ExecuteType.STANDALONE);
|
||||
newJobInfo.setProcessorType(ProcessorType.BUILT_IN);
|
||||
newJobInfo.setProcessorInfo("tech.powerjob.samples.processors.StandaloneProcessorDemo");
|
||||
newJobInfo.setDesignatedWorkers("");
|
||||
|
||||
newJobInfo.setMinCpuCores(1.1);
|
||||
newJobInfo.setMinMemorySpace(1.2);
|
||||
newJobInfo.setMinDiskSpace(1.3);
|
||||
|
||||
log.info("[TestClient] [testSaveJob] SaveJobInfoRequest: {}", JSONObject.toJSONString(newJobInfo));
|
||||
|
||||
ResultDTO<Long> resultDTO = powerJobClient.saveJob(newJobInfo);
|
||||
log.info("[TestClient] [testSaveJob] result: {}", JSONObject.toJSONString(resultDTO));
|
||||
Assertions.assertNotNull(resultDTO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCopyJob() {
|
||||
ResultDTO<Long> copyJobRes = powerJobClient.copyJob(JOB_ID);
|
||||
System.out.println(JSONObject.toJSONString(copyJobRes));
|
||||
Assertions.assertNotNull(copyJobRes);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExportJob() {
|
||||
ResultDTO<SaveJobInfoRequest> exportJobRes = powerJobClient.exportJob(JOB_ID);
|
||||
System.out.println(JSONObject.toJSONString(exportJobRes));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchJob() {
|
||||
ResultDTO<JobInfoDTO> fetchJob = powerJobClient.fetchJob(JOB_ID);
|
||||
System.out.println(JSONObject.toJSONString(fetchJob));
|
||||
Assertions.assertNotNull(fetchJob);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDisableJob() {
|
||||
ResultDTO<Void> res = powerJobClient.disableJob(JOB_ID);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnableJob() {
|
||||
ResultDTO<Void> res = powerJobClient.enableJob(JOB_ID);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteJob() {
|
||||
ResultDTO<Void> res = powerJobClient.deleteJob(JOB_ID);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRun() {
|
||||
ResultDTO<Long> res = powerJobClient.runJob(JOB_ID, null, 0);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRunJobDelay() {
|
||||
ResultDTO<Long> res = powerJobClient.runJob(JOB_ID, "this is instanceParams", 60000);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchInstanceInfo() {
|
||||
ResultDTO<InstanceInfoDTO> res = powerJobClient.fetchInstanceInfo(702482902331424832L);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testQueryInstanceInfo() {
|
||||
InstancePageQuery instancePageQuery = new InstancePageQuery();
|
||||
instancePageQuery.setJobIdEq(11L);
|
||||
instancePageQuery.setSortBy("actualTriggerTime");
|
||||
instancePageQuery.setAsc(true);
|
||||
instancePageQuery.setPageSize(3);
|
||||
instancePageQuery.setStatusIn(Lists.newArrayList(1,2,5));
|
||||
TestUtils.output(powerJobClient.queryInstanceInfo(instancePageQuery));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStopInstance() {
|
||||
ResultDTO<Void> res = powerJobClient.stopInstance(702482902331424832L);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchInstanceStatus() {
|
||||
ResultDTO<Integer> res = powerJobClient.fetchInstanceStatus(702482902331424832L);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCancelInstanceInTimeWheel() {
|
||||
ResultDTO<Long> startRes = powerJobClient.runJob(JOB_ID, "start by OhMyClient", 20000);
|
||||
System.out.println("runJob result: " + JSONObject.toJSONString(startRes));
|
||||
ResultDTO<Void> cancelRes = powerJobClient.cancelInstance(startRes.getData());
|
||||
System.out.println("cancelJob result: " + JSONObject.toJSONString(cancelRes));
|
||||
Assertions.assertTrue(cancelRes.isSuccess());
|
||||
}
|
||||
|
||||
// @Test
|
||||
// @SneakyThrows
|
||||
// void testCancelInstanceInDatabase() {
|
||||
// ResultDTO<Long> startRes = powerJobClient.runJob(15L, "start by OhMyClient", 2000000);
|
||||
// System.out.println("runJob result: " + JSONObject.toJSONString(startRes));
|
||||
//
|
||||
// // Restart server manually and clear all the data in time wheeler.
|
||||
// TimeUnit.MINUTES.sleep(1);
|
||||
//
|
||||
// ResultDTO<Void> cancelRes = powerJobClient.cancelInstance(startRes.getData());
|
||||
// System.out.println("cancelJob result: " + JSONObject.toJSONString(cancelRes));
|
||||
// Assertions.assertTrue(cancelRes.isSuccess());
|
||||
// }
|
||||
|
||||
@Test
|
||||
void testRetryInstance() {
|
||||
ResultDTO<Void> res = powerJobClient.retryInstance(169557545206153344L);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import tech.powerjob.common.response.JobInfoDTO;
|
||||
import tech.powerjob.common.response.ResultDTO;
|
||||
import tech.powerjob.common.utils.CommonUtils;
|
||||
|
||||
/**
|
||||
* 测试容灾能力
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/8/11
|
||||
*/
|
||||
@Slf4j
|
||||
public class TestClusterHA extends ClientInitializer {
|
||||
|
||||
@Test
|
||||
void testHa() {
|
||||
// 人工让 server 启停
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
|
||||
CommonUtils.easySleep(100);
|
||||
|
||||
ResultDTO<JobInfoDTO> jobInfoDTOResultDTO = powerJobClient.fetchJob(1L);
|
||||
|
||||
log.info("[TestClusterHA] response: {}", JSONObject.toJSONString(jobInfoDTOResultDTO));
|
||||
|
||||
if (!jobInfoDTOResultDTO.isSuccess()) {
|
||||
throw new RuntimeException("request failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import tech.powerjob.common.enums.ExecuteType;
|
||||
import tech.powerjob.common.enums.ProcessorType;
|
||||
import tech.powerjob.common.enums.TimeExpressionType;
|
||||
import tech.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import tech.powerjob.common.response.ResultDTO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
|
||||
/**
|
||||
* TestConcurrencyControl
|
||||
*
|
||||
* @author tjq
|
||||
* @since 1/16/21
|
||||
*/
|
||||
class TestConcurrencyControl extends ClientInitializer {
|
||||
|
||||
@Test
|
||||
void testRunJobConcurrencyControl() {
|
||||
|
||||
SaveJobInfoRequest saveJobInfoRequest = new SaveJobInfoRequest();
|
||||
saveJobInfoRequest.setJobName("test concurrency control job");
|
||||
saveJobInfoRequest.setProcessorType(ProcessorType.SHELL);
|
||||
saveJobInfoRequest.setProcessorInfo("pwd");
|
||||
saveJobInfoRequest.setExecuteType(ExecuteType.STANDALONE);
|
||||
saveJobInfoRequest.setTimeExpressionType(TimeExpressionType.API);
|
||||
saveJobInfoRequest.setMaxInstanceNum(1);
|
||||
|
||||
Long jobId = powerJobClient.saveJob(saveJobInfoRequest).getData();
|
||||
|
||||
System.out.println("jobId: " + jobId);
|
||||
|
||||
ForkJoinPool pool = new ForkJoinPool(32);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
String params = "index-" + i;
|
||||
pool.execute(() -> {
|
||||
ResultDTO<Long> res = powerJobClient.runJob(jobId, params, 0);
|
||||
System.out.println(params + ": " + res);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import tech.powerjob.common.request.query.JobInfoQuery;
|
||||
import tech.powerjob.common.enums.ExecuteType;
|
||||
import tech.powerjob.common.enums.ProcessorType;
|
||||
import tech.powerjob.common.response.JobInfoDTO;
|
||||
import tech.powerjob.common.response.ResultDTO;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test the query method
|
||||
*
|
||||
* @author tjq
|
||||
* @since 1/16/21
|
||||
*/
|
||||
@Slf4j
|
||||
class TestQuery extends ClientInitializer {
|
||||
|
||||
@Test
|
||||
void testFetchAllJob() {
|
||||
ResultDTO<List<JobInfoDTO>> allJobRes = powerJobClient.fetchAllJob();
|
||||
System.out.println(JSON.toJSONString(allJobRes));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testQueryJob() {
|
||||
JobInfoQuery jobInfoQuery = new JobInfoQuery()
|
||||
.setIdGt(-1L)
|
||||
.setIdLt(10086L)
|
||||
.setJobNameLike("DAG")
|
||||
.setGmtModifiedGt(DateUtils.addYears(new Date(), -10))
|
||||
.setGmtCreateLt(DateUtils.addDays(new Date(), 10))
|
||||
.setExecuteTypeIn(Lists.newArrayList(ExecuteType.STANDALONE.getV(), ExecuteType.BROADCAST.getV(), ExecuteType.MAP_REDUCE.getV()))
|
||||
.setProcessorTypeIn(Lists.newArrayList(ProcessorType.BUILT_IN.getV(), ProcessorType.SHELL.getV(), ProcessorType.EXTERNAL.getV()))
|
||||
.setProcessorInfoLike("tech.powerjob");
|
||||
|
||||
ResultDTO<List<JobInfoDTO>> jobQueryResult = powerJobClient.queryJob(jobInfoQuery);
|
||||
System.out.println(JSON.toJSONString(jobQueryResult));
|
||||
System.out.println(jobQueryResult.getData().size());
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
/**
|
||||
* TestUtils
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/11/21
|
||||
*/
|
||||
public class TestUtils {
|
||||
|
||||
public static void output(Object v) {
|
||||
String str = JSONObject.toJSONString(v);
|
||||
System.out.println(str);
|
||||
}
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
package tech.powerjob.client.test;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import tech.powerjob.client.PowerJobClient;
|
||||
import tech.powerjob.common.enums.ExecuteType;
|
||||
import tech.powerjob.common.enums.ProcessorType;
|
||||
import tech.powerjob.common.enums.TimeExpressionType;
|
||||
import tech.powerjob.common.enums.WorkflowNodeType;
|
||||
import tech.powerjob.common.model.PEWorkflowDAG;
|
||||
import tech.powerjob.common.request.http.SaveJobInfoRequest;
|
||||
import tech.powerjob.common.request.http.SaveWorkflowNodeRequest;
|
||||
import tech.powerjob.common.request.http.SaveWorkflowRequest;
|
||||
import tech.powerjob.common.response.ResultDTO;
|
||||
import tech.powerjob.common.response.WorkflowInfoDTO;
|
||||
import tech.powerjob.common.response.WorkflowInstanceInfoDTO;
|
||||
import tech.powerjob.common.response.WorkflowNodeInfoDTO;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Test cases for {@link PowerJobClient} workflow.
|
||||
*
|
||||
* @author tjq
|
||||
* @author Echo009
|
||||
* @since 2020/6/2
|
||||
*/
|
||||
class TestWorkflow extends ClientInitializer {
|
||||
|
||||
private static final long WF_ID = 2;
|
||||
|
||||
@Test
|
||||
void initTestData() {
|
||||
SaveJobInfoRequest base = new SaveJobInfoRequest();
|
||||
base.setJobName("DAG-Node-");
|
||||
base.setTimeExpressionType(TimeExpressionType.WORKFLOW);
|
||||
base.setExecuteType(ExecuteType.STANDALONE);
|
||||
base.setProcessorType(ProcessorType.BUILT_IN);
|
||||
base.setProcessorInfo("tech.powerjob.samples.workflow.WorkflowStandaloneProcessor");
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
SaveJobInfoRequest request = JSONObject.parseObject(JSONObject.toJSONBytes(base), SaveJobInfoRequest.class);
|
||||
request.setJobName(request.getJobName() + i);
|
||||
ResultDTO<Long> res = powerJobClient.saveJob(request);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSaveWorkflow() {
|
||||
|
||||
SaveWorkflowRequest req = new SaveWorkflowRequest();
|
||||
|
||||
req.setWfName("workflow-by-client");
|
||||
req.setWfDescription("created by client");
|
||||
req.setEnable(true);
|
||||
req.setTimeExpressionType(TimeExpressionType.API);
|
||||
|
||||
System.out.println("req ->" + JSONObject.toJSON(req));
|
||||
ResultDTO<Long> res = powerJobClient.saveWorkflow(req);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
|
||||
req.setId(res.getData());
|
||||
|
||||
// 创建节点
|
||||
SaveWorkflowNodeRequest saveWorkflowNodeRequest1 = new SaveWorkflowNodeRequest();
|
||||
saveWorkflowNodeRequest1.setJobId(1L);
|
||||
saveWorkflowNodeRequest1.setNodeName("DAG-Node-1");
|
||||
saveWorkflowNodeRequest1.setType(WorkflowNodeType.JOB.getCode());
|
||||
|
||||
SaveWorkflowNodeRequest saveWorkflowNodeRequest2 = new SaveWorkflowNodeRequest();
|
||||
saveWorkflowNodeRequest2.setJobId(1L);
|
||||
saveWorkflowNodeRequest2.setNodeName("DAG-Node-2");
|
||||
saveWorkflowNodeRequest2.setType(WorkflowNodeType.JOB.getCode());
|
||||
|
||||
|
||||
SaveWorkflowNodeRequest saveWorkflowNodeRequest3 = new SaveWorkflowNodeRequest();
|
||||
saveWorkflowNodeRequest3.setJobId(1L);
|
||||
saveWorkflowNodeRequest3.setNodeName("DAG-Node-3");
|
||||
saveWorkflowNodeRequest3.setType(WorkflowNodeType.JOB.getCode());
|
||||
|
||||
|
||||
List<WorkflowNodeInfoDTO> nodeList = powerJobClient.saveWorkflowNode(Lists.newArrayList(saveWorkflowNodeRequest1,saveWorkflowNodeRequest2,saveWorkflowNodeRequest3)).getData();
|
||||
System.out.println(nodeList);
|
||||
Assertions.assertNotNull(nodeList);
|
||||
|
||||
|
||||
// DAG 图
|
||||
List<PEWorkflowDAG.Node> nodes = Lists.newLinkedList();
|
||||
List<PEWorkflowDAG.Edge> edges = Lists.newLinkedList();
|
||||
|
||||
nodes.add(new PEWorkflowDAG.Node(nodeList.get(0).getId()));
|
||||
nodes.add(new PEWorkflowDAG.Node(nodeList.get(1).getId()));
|
||||
nodes.add(new PEWorkflowDAG.Node(nodeList.get(2).getId()));
|
||||
|
||||
edges.add(new PEWorkflowDAG.Edge(nodeList.get(0).getId(), nodeList.get(1).getId()));
|
||||
edges.add(new PEWorkflowDAG.Edge(nodeList.get(1).getId(), nodeList.get(2).getId()));
|
||||
PEWorkflowDAG peWorkflowDAG = new PEWorkflowDAG(nodes, edges);
|
||||
|
||||
// 保存完整信息
|
||||
req.setDag(peWorkflowDAG);
|
||||
res = powerJobClient.saveWorkflow(req);
|
||||
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCopyWorkflow() {
|
||||
ResultDTO<Long> res = powerJobClient.copyWorkflow(WF_ID);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testDisableWorkflow() {
|
||||
ResultDTO<Void> res = powerJobClient.disableWorkflow(WF_ID);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteWorkflow() {
|
||||
ResultDTO<Void> res = powerJobClient.deleteWorkflow(WF_ID);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEnableWorkflow() {
|
||||
ResultDTO<Void> res = powerJobClient.enableWorkflow(WF_ID);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWorkflowInfo() {
|
||||
ResultDTO<WorkflowInfoDTO> res = powerJobClient.fetchWorkflow(WF_ID);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRunWorkflow() {
|
||||
ResultDTO<Long> res = powerJobClient.runWorkflow(WF_ID, null, 0);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStopWorkflowInstance() {
|
||||
ResultDTO<Void> res = powerJobClient.stopWorkflowInstance(149962433421639744L);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRetryWorkflowInstance() {
|
||||
ResultDTO<Void> res = powerJobClient.retryWorkflowInstance(149962433421639744L);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMarkWorkflowNodeAsSuccess() {
|
||||
ResultDTO<Void> res = powerJobClient.markWorkflowNodeAsSuccess(149962433421639744L, 1L);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFetchWfInstanceInfo() {
|
||||
ResultDTO<WorkflowInstanceInfoDTO> res = powerJobClient.fetchWorkflowInstanceInfo(149962433421639744L);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRunWorkflowPlus() {
|
||||
ResultDTO<Long> res = powerJobClient.runWorkflow(WF_ID, "this is init Params 2", 90000);
|
||||
System.out.println(res);
|
||||
Assertions.assertNotNull(res);
|
||||
}
|
||||
}
|
@ -4,23 +4,24 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>powerjob</artifactId>
|
||||
<groupId>com.github.kfcfans</groupId>
|
||||
<version>2.0.0</version>
|
||||
<groupId>tech.powerjob</groupId>
|
||||
<version>5.1.1</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>powerjob-common</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<version>5.1.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<slf4j.version>1.7.30</slf4j.version>
|
||||
<commons.lang.version>3.10</commons.lang.version>
|
||||
<commons.io.version>2.6</commons.io.version>
|
||||
<guava.version>29.0-jre</guava.version>
|
||||
<slf4j.version>1.7.36</slf4j.version>
|
||||
<commons.lang.version>3.12.0</commons.lang.version>
|
||||
<commons.io.version>2.11.0</commons.io.version>
|
||||
<guava.version>31.1-jre</guava.version>
|
||||
<okhttp.version>3.14.9</okhttp.version>
|
||||
<akka.version>2.6.4</akka.version>
|
||||
<junit.version>5.6.1</junit.version>
|
||||
<kryo.version>5.3.0</kryo.version>
|
||||
<jackson.version>2.14.3</jackson.version>
|
||||
<junit.version>5.9.0</junit.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -52,23 +53,6 @@
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- akka remote -->
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-remote_2.13</artifactId>
|
||||
<version>${akka.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-serialization-jackson_2.13</artifactId>
|
||||
<version>${akka.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-slf4j_2.13</artifactId>
|
||||
<version>${akka.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- commons-io -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
@ -76,7 +60,32 @@
|
||||
<version>${commons.io.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Junit 测试 -->
|
||||
<!-- kryo 超超超高性能序列化框架 -->
|
||||
<dependency>
|
||||
<groupId>com.esotericsoftware.kryo</groupId>
|
||||
<artifactId>kryo5</artifactId>
|
||||
<version>${kryo.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<!-- 解决 Java8 data/time 类型处理问题 #869 -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Junit tests -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
|
@ -1,13 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
|
||||
/**
|
||||
* 部署环境
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/3
|
||||
*/
|
||||
public enum Env {
|
||||
DAILY,
|
||||
PRE,
|
||||
PRODUCT
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
|
||||
/**
|
||||
* 公共常量
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/31
|
||||
*/
|
||||
public class OmsConstant {
|
||||
|
||||
public static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
public static final String TIME_PATTERN_PLUS = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
|
||||
public static final String NONE = "N/A";
|
||||
|
||||
public static final String COMMA = ",";
|
||||
public static final String LINE_SEPARATOR = "\r\n";
|
||||
|
||||
public static final String JSON_MEDIA_TYPE = "application/json; charset=utf-8";
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* OMS 序列化标记接口
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/16
|
||||
*/
|
||||
public interface OmsSerializable extends Serializable {
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
|
||||
import java.net.NetworkInterface;
|
||||
|
||||
/**
|
||||
* 通过 JVM 启动参数传入的配置信息
|
||||
*
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/8/8
|
||||
*/
|
||||
public class PowerJobDKey {
|
||||
|
||||
/**
|
||||
* The property name for {@link NetworkInterface#getDisplayName() the name of network interface} that the PowerJob application prefers
|
||||
*/
|
||||
public static final String PREFERRED_NETWORK_INTERFACE = "powerjob.network.interface.preferred";
|
||||
|
||||
/**
|
||||
* Java regular expressions for network interfaces that will be ignored.
|
||||
*/
|
||||
public static final String IGNORED_NETWORK_INTERFACE_REGEX = "powerjob.network.interface.ignored";
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
|
||||
/**
|
||||
* RemoteConstant
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/17
|
||||
*/
|
||||
public class RemoteConstant {
|
||||
|
||||
|
||||
/* ************************ AKKA WORKER ************************ */
|
||||
public static final int DEFAULT_WORKER_PORT = 27777;
|
||||
|
||||
public static final String WORKER_ACTOR_SYSTEM_NAME = "oms";
|
||||
|
||||
public static final String Task_TRACKER_ACTOR_NAME = "task_tracker";
|
||||
public static final String PROCESSOR_TRACKER_ACTOR_NAME = "processor_tracker";
|
||||
public static final String WORKER_ACTOR_NAME = "worker";
|
||||
public static final String TROUBLESHOOTING_ACTOR_NAME = "troubleshooting";
|
||||
|
||||
public static final String WORKER_AKKA_CONFIG_NAME = "oms-worker.akka.conf";
|
||||
|
||||
|
||||
/* ************************ AKKA SERVER ************************ */
|
||||
public static final String SERVER_ACTOR_SYSTEM_NAME = "oms-server";
|
||||
|
||||
public static final String SERVER_ACTOR_NAME = "server_actor";
|
||||
public static final String SERVER_FRIEND_ACTOR_NAME = "friend_actor";
|
||||
public static final String SERVER_TROUBLESHOOTING_ACTOR_NAME = "server_troubleshooting_actor";
|
||||
public static final String SERVER_AKKA_CONFIG_NAME = "oms-server.akka.conf";
|
||||
|
||||
|
||||
/* ************************ OTHERS ************************ */
|
||||
public static final String EMPTY_ADDRESS = "N/A";
|
||||
public static final long DEFAULT_TIMEOUT_MS = 5000;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
|
||||
/**
|
||||
* 系统生成的任务实例运行结果
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/11
|
||||
*/
|
||||
public class SystemInstanceResult {
|
||||
|
||||
/* *********** 普通instance 专用 *********** */
|
||||
|
||||
// 同时运行的任务实例数过多
|
||||
public static final String TOO_MANY_INSTANCES = "too many instances(%d>%d)";
|
||||
// 无可用worker
|
||||
public static final String NO_WORKER_AVAILABLE = "no worker available";
|
||||
// 任务执行超时
|
||||
public static final String INSTANCE_EXECUTE_TIMEOUT = "instance execute timeout";
|
||||
// 创建根任务失败
|
||||
public static final String TASK_INIT_FAILED = "create root task failed";
|
||||
// 未知错误
|
||||
public static final String UNKNOWN_BUG = "unknown bug";
|
||||
// TaskTracker 长时间未上报
|
||||
public static final String REPORT_TIMEOUT = "worker report timeout, maybe TaskTracker down";
|
||||
|
||||
/* *********** workflow 专用 *********** */
|
||||
public static final String MIDDLE_JOB_FAILED = "middle job failed";
|
||||
public static final String MIDDLE_JOB_STOPPED = "middle job stopped by user";
|
||||
public static final String CAN_NOT_FIND_JOB = "can't find some job";
|
||||
|
||||
// 被用户手动停止
|
||||
public static final String STOPPED_BY_USER = "stopped by user";
|
||||
public static final String CANCELED_BY_USER = "canceled by user";
|
||||
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 时间表达式类型
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/30
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum TimeExpressionType {
|
||||
|
||||
API(1),
|
||||
CRON(2),
|
||||
FIX_RATE(3),
|
||||
FIX_DELAY(4),
|
||||
WORKFLOW(5);
|
||||
|
||||
int v;
|
||||
|
||||
public static final List<Integer> frequentTypes = Lists.newArrayList(FIX_RATE.v, FIX_DELAY.v);
|
||||
|
||||
public static TimeExpressionType of(int v) {
|
||||
for (TimeExpressionType type : values()) {
|
||||
if (type.v == v) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("unknown TimeExpressionType of " + v);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.model;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 已部署的容器信息
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/18
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DeployedContainerInfo implements OmsSerializable {
|
||||
|
||||
// 容器ID
|
||||
private Long containerId;
|
||||
// 版本
|
||||
private String version;
|
||||
// 部署时间
|
||||
private long deployedTime;
|
||||
// 机器地址(无需上报)
|
||||
private String workerAddress;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Git代码库信息
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/17
|
||||
*/
|
||||
@Data
|
||||
public class GitRepoInfo {
|
||||
// 仓库地址
|
||||
private String repo;
|
||||
// 分支名称
|
||||
private String branch;
|
||||
// 用户名
|
||||
private String username;
|
||||
// 密码
|
||||
private String password;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.model;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 任务实例的运行详细信息
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/11
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class InstanceDetail implements OmsSerializable {
|
||||
|
||||
// 任务预计执行时间
|
||||
private Long expectedTriggerTime;
|
||||
// 任务整体开始时间
|
||||
private Long actualTriggerTime;
|
||||
// 任务整体结束时间(可能不存在)
|
||||
private Long finishedTime;
|
||||
// 任务状态
|
||||
private Integer status;
|
||||
// 任务执行结果(可能不存在)
|
||||
private String result;
|
||||
// TaskTracker地址
|
||||
private String taskTrackerAddress;
|
||||
// 启动参数
|
||||
private String instanceParams;
|
||||
|
||||
// MR或BD任务专用
|
||||
private TaskDetail taskDetail;
|
||||
// 秒级任务专用
|
||||
private List<SubInstanceDetail> subInstanceDetails;
|
||||
|
||||
// 重试次数
|
||||
private Long runningTimes;
|
||||
|
||||
// 扩展字段,中间件升级不易,最好不要再改 common 包了...否则 server worker 版本不兼容
|
||||
private String extra;
|
||||
|
||||
// 秒级任务的 extra -> List<SubInstanceDetail>
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class SubInstanceDetail implements OmsSerializable {
|
||||
private long subInstanceId;
|
||||
private Long startTime;
|
||||
private Long finishedTime;
|
||||
private String result;
|
||||
private int status;
|
||||
}
|
||||
|
||||
// MapReduce 和 Broadcast 任务的 extra ->
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public static class TaskDetail implements OmsSerializable {
|
||||
private long totalTaskNum;
|
||||
private long succeedTaskNum;
|
||||
private long failedTaskNum;
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.model;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 任务实例日志对象
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/21
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InstanceLogContent implements OmsSerializable {
|
||||
|
||||
// 实例ID
|
||||
private long instanceId;
|
||||
// 日志提交时间
|
||||
private long logTime;
|
||||
// 日志内容
|
||||
private String logContent;
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.model;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Point & Edge DAG 表示法
|
||||
* 点 + 线,易于表达和传播
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/26
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class PEWorkflowDAG implements Serializable {
|
||||
|
||||
// DAG 图(点线表示法)
|
||||
private List<Node> nodes;
|
||||
private List<Edge> edges;
|
||||
|
||||
// 点
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Node implements Serializable {
|
||||
private Long jobId;
|
||||
private String jobName;
|
||||
|
||||
// 运行时参数,图定义不需要
|
||||
@JsonSerialize(using= ToStringSerializer.class)
|
||||
private Long instanceId;
|
||||
private Integer status;
|
||||
private String result;
|
||||
|
||||
public Node(Long jobId, String jobName) {
|
||||
this.jobId = jobId;
|
||||
this.jobName = jobName;
|
||||
}
|
||||
}
|
||||
|
||||
// 边 jobId -> jobId
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class Edge implements Serializable {
|
||||
private Long from;
|
||||
private Long to;
|
||||
}
|
||||
|
||||
public PEWorkflowDAG(@Nonnull List<Node> nodes, @Nullable List<Edge> edges) {
|
||||
this.nodes = nodes;
|
||||
this.edges = edges == null ? Lists.newLinkedList() : edges;
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.model;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 系统指标
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/25
|
||||
*/
|
||||
@Data
|
||||
public class SystemMetrics implements OmsSerializable, Comparable<SystemMetrics> {
|
||||
|
||||
// CPU核心数量
|
||||
private int cpuProcessors;
|
||||
// CPU负载(负载 和 使用率 是两个完全不同的概念,Java 无法获取 CPU 使用率,只能获取负载)
|
||||
private double cpuLoad;
|
||||
|
||||
// 内存(单位 GB)
|
||||
private double jvmUsedMemory;
|
||||
private double jvmMaxMemory;
|
||||
// 内存占用(0.X,非百分比)
|
||||
private double jvmMemoryUsage;
|
||||
|
||||
// 磁盘(单位 GB)
|
||||
private double diskUsed;
|
||||
private double diskTotal;
|
||||
// 磁盘占用(0.X,非百分比)
|
||||
private double diskUsage;
|
||||
|
||||
// 缓存分数
|
||||
private int score;
|
||||
|
||||
@Override
|
||||
public int compareTo(SystemMetrics that) {
|
||||
// 降序排列
|
||||
return that.calculateScore() - this.calculateScore();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算得分情况,内存 & CPU (磁盘不参与计算)
|
||||
* @return 得分情况
|
||||
*/
|
||||
public int calculateScore() {
|
||||
|
||||
if (score > 0) {
|
||||
return score;
|
||||
}
|
||||
|
||||
// 对于 TaskTracker 来说,内存是任务顺利完成的关键,因此内存 2 块钱 1GB
|
||||
double memScore = (jvmMaxMemory - jvmUsedMemory) * 2;
|
||||
// CPU 剩余负载,1 块钱 1 斤
|
||||
double cpuScore = cpuProcessors - cpuLoad;
|
||||
// Indian Windows 无法获取 CpuLoad,为 -1,固定为 1
|
||||
if (cpuScore > cpuProcessors) {
|
||||
cpuScore = 1;
|
||||
}
|
||||
|
||||
score = (int) (memScore + cpuScore);
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* 该机器是否可用
|
||||
* @param minCPUCores 判断标准之最低可用CPU核心数量
|
||||
* @param minMemorySpace 判断标准之最低可用内存
|
||||
* @param minDiskSpace 判断标准之最低可用磁盘空间
|
||||
* @return 是否可用
|
||||
*/
|
||||
public boolean available(double minCPUCores, double minMemorySpace, double minDiskSpace) {
|
||||
|
||||
double availableMemory = jvmMaxMemory - jvmUsedMemory;
|
||||
double availableDisk = diskTotal - diskUsed;
|
||||
|
||||
if (availableMemory < minMemorySpace || availableDisk < minDiskSpace) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// cpuLoad 为负数代表无法获取,不判断。等于 0 为最理想情况,CPU 空载,不需要判断
|
||||
if (cpuLoad <= 0 || minCPUCores <= 0) {
|
||||
return true;
|
||||
}
|
||||
return minCPUCores < (cpuProcessors - cpuLoad);
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.request;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 服务器查询实例运行状态,需要返回详细的运行数据
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/10
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ServerQueryInstanceStatusReq implements OmsSerializable {
|
||||
private Long instanceId;
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.request;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务端调度任务请求(一次任务处理的入口)
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/17
|
||||
*/
|
||||
@Data
|
||||
public class ServerScheduleJobReq implements OmsSerializable {
|
||||
|
||||
// 可用处理器地址,可能多值,逗号分隔
|
||||
private List<String> allWorkerAddress;
|
||||
|
||||
/* *********************** 任务相关属性 *********************** */
|
||||
|
||||
/**
|
||||
* 任务ID,当更换Server后需要根据 JobId 重新查询任务元数据
|
||||
*/
|
||||
private Long jobId;
|
||||
|
||||
private Long wfInstanceId;
|
||||
/**
|
||||
* 基础信息
|
||||
*/
|
||||
private Long instanceId;
|
||||
|
||||
/**
|
||||
* 任务执行处理器信息
|
||||
*/
|
||||
// 任务执行类型,单机、广播、MR
|
||||
private String executeType;
|
||||
// 处理器类型(JavaBean、Jar、脚本等)
|
||||
private String processorType;
|
||||
// 处理器信息
|
||||
private String processorInfo;
|
||||
|
||||
|
||||
/**
|
||||
* 超时时间
|
||||
*/
|
||||
// 整个任务的总体超时时间
|
||||
private long instanceTimeoutMS;
|
||||
|
||||
/**
|
||||
* 任务运行参数
|
||||
*/
|
||||
// 任务级别的参数,相当于类的static变量
|
||||
private String jobParams;
|
||||
// 实例级别的参数,相当于类的普通变量(API触发专用,从API触发处带入)
|
||||
private String instanceParams;
|
||||
|
||||
// 每台机器的处理线程数上限
|
||||
private int threadConcurrency;
|
||||
// 子任务重试次数(任务本身的重试机制由server控制)
|
||||
private int taskRetryNum;
|
||||
|
||||
/**
|
||||
* 定时执行信息
|
||||
*/
|
||||
// 时间表达式类型(CRON/API/FIX_RATE/FIX_DELAY)
|
||||
private String timeExpressionType;
|
||||
// 时间表达式,CRON/NULL/LONG/LONG(单位MS)
|
||||
private String timeExpression;
|
||||
|
||||
// 最大同时运行任务数,默认 1
|
||||
private Integer maxInstanceNum;
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.request;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* TaskTracker 将状态上报给服务器
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/17
|
||||
*/
|
||||
@Data
|
||||
public class TaskTrackerReportInstanceStatusReq implements OmsSerializable {
|
||||
|
||||
private Long jobId;
|
||||
private Long instanceId;
|
||||
private Long wfInstanceId;
|
||||
|
||||
private int instanceStatus;
|
||||
|
||||
private String result;
|
||||
|
||||
/* ********* 统计信息 ********* */
|
||||
private long totalTaskNum;
|
||||
private long succeedTaskNum;
|
||||
private long failedTaskNum;
|
||||
|
||||
private long startTime;
|
||||
private long reportTime;
|
||||
private String sourceAddress;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.request;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import com.github.kfcfans.powerjob.common.model.DeployedContainerInfo;
|
||||
import com.github.kfcfans.powerjob.common.model.SystemMetrics;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Worker 上报健康信息(worker定时发送的heartbeat)
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/25
|
||||
*/
|
||||
@Data
|
||||
public class WorkerHeartbeat implements OmsSerializable {
|
||||
|
||||
// 本机地址 -> IP:port
|
||||
private String workerAddress;
|
||||
// 当前 appName
|
||||
private String appName;
|
||||
// 当前 appId
|
||||
private Long appId;
|
||||
// 当前时间
|
||||
private long heartbeatTime;
|
||||
// 当前加载的容器(容器名称 -> 容器版本)
|
||||
private List<DeployedContainerInfo> containerInfos;
|
||||
// worker 版本信息
|
||||
private String version;
|
||||
// 扩展字段
|
||||
private String extra;
|
||||
|
||||
private SystemMetrics systemMetrics;
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.request.http;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.ExecuteType;
|
||||
import com.github.kfcfans.powerjob.common.ProcessorType;
|
||||
import com.github.kfcfans.powerjob.common.TimeExpressionType;
|
||||
import com.github.kfcfans.powerjob.common.utils.CommonUtils;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 创建/修改 JobInfo 请求
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/30
|
||||
*/
|
||||
@Data
|
||||
public class SaveJobInfoRequest {
|
||||
|
||||
// 任务ID(jobId),null -> 插入,否则为更新
|
||||
private Long id;
|
||||
/* ************************** 任务基本信息 ************************** */
|
||||
// 任务名称
|
||||
private String jobName;
|
||||
// 任务描述
|
||||
private String jobDescription;
|
||||
// 任务所属的应用ID(Client无需填写该参数,自动填充)
|
||||
private Long appId;
|
||||
// 任务自带的参数
|
||||
private String jobParams;
|
||||
|
||||
/* ************************** 定时参数 ************************** */
|
||||
// 时间表达式类型(CRON/API/FIX_RATE/FIX_DELAY)
|
||||
private TimeExpressionType timeExpressionType;
|
||||
// 时间表达式,CRON/NULL/LONG/LONG
|
||||
private String timeExpression;
|
||||
|
||||
|
||||
/* ************************** 执行方式 ************************** */
|
||||
// 执行类型,单机/广播/MR
|
||||
private ExecuteType executeType;
|
||||
// 执行器类型,Java/Shell
|
||||
private ProcessorType processorType;
|
||||
// 执行器信息
|
||||
private String processorInfo;
|
||||
|
||||
|
||||
/* ************************** 运行时配置 ************************** */
|
||||
// 最大同时运行任务数,0 代表不限
|
||||
private Integer maxInstanceNum = 0;
|
||||
// 并发度,同时执行的线程数量
|
||||
private Integer concurrency = 5;
|
||||
// 任务整体超时时间
|
||||
private Long instanceTimeLimit = 0L;
|
||||
|
||||
/* ************************** 重试配置 ************************** */
|
||||
private Integer instanceRetryNum = 0;
|
||||
private Integer taskRetryNum = 0;
|
||||
|
||||
/* ************************** 繁忙机器配置 ************************** */
|
||||
// 最低CPU核心数量,0代表不限
|
||||
private double minCpuCores = 0;
|
||||
// 最低内存空间,单位 GB,0代表不限
|
||||
private double minMemorySpace = 0;
|
||||
// 最低磁盘空间,单位 GB,0代表不限
|
||||
private double minDiskSpace = 0;
|
||||
|
||||
// 1 正常运行,2 停止(不再调度)
|
||||
private boolean enable = true;
|
||||
|
||||
|
||||
/* ************************** 集群配置 ************************** */
|
||||
// 指定机器运行,空代表不限,非空则只会使用其中的机器运行(多值逗号分割)
|
||||
private String designatedWorkers;
|
||||
// 最大机器数量
|
||||
private Integer maxWorkerCount = 0;
|
||||
|
||||
// 报警用户ID列表
|
||||
private List<Long> notifyUserIds;
|
||||
|
||||
|
||||
public void valid() {
|
||||
CommonUtils.requireNonNull(jobName, "jobName can't be empty");
|
||||
CommonUtils.requireNonNull(appId, "appId can't be empty");
|
||||
CommonUtils.requireNonNull(processorInfo, "processorInfo can't be empty");
|
||||
CommonUtils.requireNonNull(executeType, "executeType can't be empty");
|
||||
CommonUtils.requireNonNull(processorType, "processorType can't be empty");
|
||||
CommonUtils.requireNonNull(timeExpressionType, "timeExpressionType can't be empty");
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.response;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.InstanceStatus;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* instanceInfo 对外输出对象
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/14
|
||||
*/
|
||||
@Data
|
||||
public class InstanceInfoDTO {
|
||||
|
||||
// 任务ID
|
||||
private Long jobId;
|
||||
// 任务所属应用的ID,冗余提高查询效率
|
||||
private Long appId;
|
||||
// 任务实例ID
|
||||
private Long instanceId;
|
||||
// 工作流实例ID
|
||||
private Long wfInstanceId;
|
||||
// 任务实例参数
|
||||
private String instanceParams;
|
||||
/**
|
||||
* 任务状态 {@link InstanceStatus}
|
||||
*/
|
||||
private int status;
|
||||
// 该任务实例的类型,普通/工作流(InstanceType)
|
||||
private Integer type;
|
||||
// 执行结果
|
||||
private String result;
|
||||
// 预计触发时间
|
||||
private Long expectedTriggerTime;
|
||||
// 实际触发时间
|
||||
private Long actualTriggerTime;
|
||||
// 结束时间
|
||||
private Long finishedTime;
|
||||
// TaskTracker地址
|
||||
private String taskTrackerAddress;
|
||||
|
||||
// 总共执行的次数(用于重试判断)
|
||||
private Long runningTimes;
|
||||
|
||||
private Date gmtCreate;
|
||||
private Date gmtModified;
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* jobInfo 对外输出对象
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/14
|
||||
*/
|
||||
@Data
|
||||
public class JobInfoDTO {
|
||||
|
||||
private Long id;
|
||||
|
||||
/* ************************** 任务基本信息 ************************** */
|
||||
// 任务名称
|
||||
private String jobName;
|
||||
// 任务描述
|
||||
private String jobDescription;
|
||||
// 任务所属的应用ID
|
||||
private Long appId;
|
||||
// 任务自带的参数
|
||||
private String jobParams;
|
||||
|
||||
/* ************************** 定时参数 ************************** */
|
||||
// 时间表达式类型(CRON/API/FIX_RATE/FIX_DELAY)
|
||||
private Integer timeExpressionType;
|
||||
// 时间表达式,CRON/NULL/LONG/LONG
|
||||
private String timeExpression;
|
||||
|
||||
/* ************************** 执行方式 ************************** */
|
||||
// 执行类型,单机/广播/MR
|
||||
private Integer executeType;
|
||||
// 执行器类型,Java/Shell
|
||||
private Integer processorType;
|
||||
// 执行器信息
|
||||
private String processorInfo;
|
||||
|
||||
/* ************************** 运行时配置 ************************** */
|
||||
// 最大同时运行任务数,默认 1
|
||||
private Integer maxInstanceNum;
|
||||
// 并发度,同时执行某个任务的最大线程数量
|
||||
private Integer concurrency;
|
||||
// 任务整体超时时间
|
||||
private Long instanceTimeLimit;
|
||||
|
||||
/* ************************** 重试配置 ************************** */
|
||||
private Integer instanceRetryNum;
|
||||
private Integer taskRetryNum;
|
||||
|
||||
// 1 正常运行,2 停止(不再调度)
|
||||
private Integer status;
|
||||
// 下一次调度时间
|
||||
private Long nextTriggerTime;
|
||||
|
||||
/* ************************** 繁忙机器配置 ************************** */
|
||||
// 最低CPU核心数量,0代表不限
|
||||
private double minCpuCores;
|
||||
// 最低内存空间,单位 GB,0代表不限
|
||||
private double minMemorySpace;
|
||||
// 最低磁盘空间,单位 GB,0代表不限
|
||||
private double minDiskSpace;
|
||||
|
||||
/* ************************** 集群配置 ************************** */
|
||||
// 指定机器运行,空代表不限,非空则只会使用其中的机器运行(多值逗号分割)
|
||||
private String designatedWorkers;
|
||||
// 最大机器数量
|
||||
private Integer maxWorkerCount;
|
||||
|
||||
// 报警用户ID列表,多值逗号分隔
|
||||
private String notifyUserIds;
|
||||
|
||||
private Date gmtCreate;
|
||||
private Date gmtModified;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.response;
|
||||
|
||||
import com.github.kfcfans.powerjob.common.OmsSerializable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
/**
|
||||
* 请求返回的结果对象
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/30
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class ResultDTO<T> implements OmsSerializable {
|
||||
|
||||
private boolean success;
|
||||
// 数据(success为 true 时存在)
|
||||
private T data;
|
||||
// 错误信息(success为 false 时存在)
|
||||
private String message;
|
||||
|
||||
public static <T> ResultDTO<T> success(T data) {
|
||||
ResultDTO<T> r = new ResultDTO<>();
|
||||
r.success = true;
|
||||
r.data = data;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T> ResultDTO<T> failed(String message) {
|
||||
ResultDTO<T> r = new ResultDTO<>();
|
||||
r.success = false;
|
||||
r.message = message;
|
||||
return r;
|
||||
}
|
||||
|
||||
public static <T> ResultDTO<T> failed(Throwable t) {
|
||||
return failed(ExceptionUtils.getStackTrace(t));
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.response;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* workflowInfo 对外输出对象
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/6/2
|
||||
*/
|
||||
@Data
|
||||
public class WorkflowInfoDTO {
|
||||
|
||||
private Long id;
|
||||
private String wfName;
|
||||
private String wfDescription;
|
||||
|
||||
// 所属应用ID
|
||||
private Long appId;
|
||||
|
||||
// 工作流的DAG图信息(点线式DAG的json)
|
||||
private String peDAG;
|
||||
|
||||
/* ************************** 定时参数 ************************** */
|
||||
// 时间表达式类型(CRON/API/FIX_RATE/FIX_DELAY)
|
||||
private Integer timeExpressionType;
|
||||
// 时间表达式,CRON/NULL/LONG/LONG
|
||||
private String timeExpression;
|
||||
|
||||
// 最大同时运行的工作流个数,默认 1
|
||||
private Integer maxWfInstanceNum;
|
||||
|
||||
// 1 正常运行,2 停止(不再调度)
|
||||
private Integer status;
|
||||
// 下一次调度时间
|
||||
private Long nextTriggerTime;
|
||||
|
||||
// 工作流整体失败的报警
|
||||
private String notifyUserIds;
|
||||
|
||||
private Date gmtCreate;
|
||||
private Date gmtModified;
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.github.kfcfans.powerjob.common.utils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.kfcfans.powerjob.common.PowerJobException;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
/**
|
||||
* JSON工具类
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/16
|
||||
*/
|
||||
public class JsonUtils {
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
static {
|
||||
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
|
||||
}
|
||||
|
||||
public static String toJSONString(Object obj) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(obj);
|
||||
}catch (Exception ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String toJSONStringUnsafe(Object obj) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(obj);
|
||||
}catch (Exception e) {
|
||||
throw new PowerJobException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toBytes(Object obj) {
|
||||
try {
|
||||
return objectMapper.writeValueAsBytes(obj);
|
||||
}catch (Exception ignore) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T parseObject(String json, Class<T> clz) throws JsonProcessingException {
|
||||
return objectMapper.readValue(json, clz);
|
||||
}
|
||||
|
||||
public static <T> T parseObject(byte[] b, Class<T> clz) throws Exception {
|
||||
return objectMapper.readValue(b, clz);
|
||||
}
|
||||
|
||||
public static <T> T parseObject(byte[] b, TypeReference<T> typeReference) throws Exception {
|
||||
return objectMapper.readValue(b, typeReference);
|
||||
}
|
||||
|
||||
public static <T> T parseObjectUnsafe(String json, Class<T> clz) {
|
||||
try {
|
||||
return objectMapper.readValue(json, clz);
|
||||
}catch (Exception e) {
|
||||
ExceptionUtils.rethrow(e);
|
||||
}
|
||||
throw new PowerJobException("impossible");
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
package tech.powerjob.common;
|
||||
|
||||
/**
|
||||
* 容器常量
|
||||
* Container constants.
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/15
|
||||
@ -9,13 +9,16 @@ package com.github.kfcfans.powerjob.common;
|
||||
public class ContainerConstant {
|
||||
|
||||
/**
|
||||
* spring-context 配置文件名称
|
||||
* Spring-context configuration file name of the container.
|
||||
*/
|
||||
public static final String SPRING_CONTEXT_FILE_NAME = "oms-worker-container-spring-context.xml";
|
||||
|
||||
/**
|
||||
* container 属性文件名称
|
||||
* Property file name of the container.
|
||||
*/
|
||||
public static final String CONTAINER_PROPERTIES_FILE_NAME = "oms-worker-container.properties";
|
||||
/**
|
||||
* Package name of the container.
|
||||
*/
|
||||
public static final String CONTAINER_PACKAGE_NAME_KEY = "PACKAGE_NAME";
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package tech.powerjob.common;
|
||||
|
||||
/**
|
||||
* Common constants.
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/31
|
||||
*/
|
||||
public class OmsConstant {
|
||||
|
||||
/**
|
||||
* package name
|
||||
*/
|
||||
public static final String PACKAGE = "tech.powerjob";
|
||||
|
||||
public static final int SERVER_DEFAULT_AKKA_PORT = 10086;
|
||||
public static final int SERVER_DEFAULT_HTTP_PORT = 10010;
|
||||
|
||||
public static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
public static final String TIME_PATTERN_PLUS = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
|
||||
public static final String NONE = "N/A";
|
||||
|
||||
public static final String COMMA = ",";
|
||||
|
||||
public static final String AND = "&";
|
||||
|
||||
public static final String EQUAL = "=";
|
||||
public static final String LINE_SEPARATOR = "\r\n";
|
||||
|
||||
public static final String HTTP_HEADER_CONTENT_TYPE = "Content-Type";
|
||||
public static final String JSON_MEDIA_TYPE = "application/json; charset=utf-8";
|
||||
|
||||
public static final String NULL = "null";
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.github.kfcfans.powerjob.common;
|
||||
package tech.powerjob.common;
|
||||
|
||||
/**
|
||||
* OpenAPI 常量
|
||||
@ -8,34 +8,62 @@ package com.github.kfcfans.powerjob.common;
|
||||
*/
|
||||
public class OpenAPIConstant {
|
||||
|
||||
private OpenAPIConstant(){
|
||||
|
||||
}
|
||||
|
||||
public static final String WEB_PATH = "/openApi";
|
||||
|
||||
public static final String ASSERT = "/assert";
|
||||
|
||||
public static final String AUTH_APP = "/authApp";
|
||||
|
||||
/* ************* JOB 区 ************* */
|
||||
|
||||
public static final String SAVE_JOB = "/saveJob";
|
||||
public static final String COPY_JOB = "/copyJob";
|
||||
|
||||
public static final String EXPORT_JOB = "/exportJob";
|
||||
public static final String FETCH_JOB = "/fetchJob";
|
||||
public static final String FETCH_ALL_JOB = "/fetchAllJob";
|
||||
public static final String QUERY_JOB = "/queryJob";
|
||||
public static final String DISABLE_JOB = "/disableJob";
|
||||
public static final String ENABLE_JOB = "/enableJob";
|
||||
public static final String DELETE_JOB = "/deleteJob";
|
||||
public static final String RUN_JOB = "/runJob";
|
||||
|
||||
/* ************* Instance 区 ************* */
|
||||
|
||||
public static final String STOP_INSTANCE = "/stopInstance";
|
||||
public static final String CANCEL_INSTANCE = "/cancelInstance";
|
||||
public static final String RETRY_INSTANCE = "/retryInstance";
|
||||
public static final String FETCH_INSTANCE_STATUS = "/fetchInstanceStatus";
|
||||
public static final String FETCH_INSTANCE_INFO = "/fetchInstanceInfo";
|
||||
public static final String QUERY_INSTANCE = "/queryInstance";
|
||||
|
||||
/* ************* Workflow 区 ************* */
|
||||
|
||||
public static final String SAVE_WORKFLOW = "/saveWorkflow";
|
||||
public static final String COPY_WORKFLOW = "/copyWorkflow";
|
||||
public static final String FETCH_WORKFLOW = "/fetchWorkflow";
|
||||
public static final String DISABLE_WORKFLOW = "/disableWorkflow";
|
||||
public static final String ENABLE_WORKFLOW = "/enableWorkflow";
|
||||
public static final String DELETE_WORKFLOW = "/deleteWorkflow";
|
||||
public static final String RUN_WORKFLOW = "/runWorkflow";
|
||||
public static final String SAVE_WORKFLOW_NODE = "/addWorkflowNode";
|
||||
|
||||
/* ************* WorkflowInstance 区 ************* */
|
||||
|
||||
public static final String STOP_WORKFLOW_INSTANCE = "/stopWfInstance";
|
||||
public static final String RETRY_WORKFLOW_INSTANCE = "/retryWfInstance";
|
||||
public static final String FETCH_WORKFLOW_INSTANCE_INFO = "/fetchWfInstanceInfo";
|
||||
public static final String MARK_WORKFLOW_NODE_AS_SUCCESS = "/markWorkflowNodeAsSuccess";
|
||||
|
||||
/* ************* 鉴权 ************* */
|
||||
|
||||
public static final String REQUEST_HEADER_ACCESS_TOKEN = "X-POWERJOB-ACCESS-TOKEN";
|
||||
|
||||
public static final String REQUEST_HEADER_APP_ID = "X-POWERJOB-APP-ID";
|
||||
|
||||
public static final String RESPONSE_HEADER_AUTH_STATUS = "X-POWERJOB-AUTH-PASSED";
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package tech.powerjob.common;
|
||||
|
||||
import java.net.NetworkInterface;
|
||||
|
||||
/**
|
||||
* 通过 JVM 启动参数传入的配置信息
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/8/8
|
||||
*/
|
||||
public class PowerJobDKey {
|
||||
|
||||
/**
|
||||
* The property name for {@link NetworkInterface#getDisplayName() the name of network interface} that the PowerJob application prefers
|
||||
*/
|
||||
public static final String PREFERRED_NETWORK_INTERFACE = "powerjob.network.interface.preferred";
|
||||
|
||||
/**
|
||||
* 绑定地址,一般填写本机网卡地址
|
||||
*/
|
||||
public static final String BIND_LOCAL_ADDRESS = "powerjob.network.local.address";
|
||||
/**
|
||||
* 外部地址,可选,默认与绑定地址相同。当存在 NAT 等场景时可通过单独传递外部地址来实现通讯
|
||||
*/
|
||||
public static final String NT_EXTERNAL_ADDRESS = "powerjob.network.external.address";
|
||||
public static final String NT_EXTERNAL_PORT = "powerjob.network.external.port";
|
||||
|
||||
/**
|
||||
* Java regular expressions for network interfaces that will be ignored.
|
||||
*/
|
||||
public static final String IGNORED_NETWORK_INTERFACE_REGEX = "powerjob.network.interface.ignored";
|
||||
|
||||
/**
|
||||
* Enables compression during data transfer, such as gzip under the HTTP protocol. default value is 'false'
|
||||
* Note that enabling compression reduces network usage, but increases CPU consumption
|
||||
*/
|
||||
public static final String TRANSPORTER_USE_COMPRESSING = "powerjob.transporter.compression.enabled";
|
||||
|
||||
/**
|
||||
* keep-alive connection timeout(in seconds), value <= 0 means disable keepalive. default value is 75
|
||||
*/
|
||||
public static final String TRANSPORTER_KEEP_ALIVE_TIMEOUT = "powerjob.transporter.keepalive.timeout";
|
||||
|
||||
public static final String WORKER_STATUS_CHECK_PERIOD = "powerjob.worker.status-check.normal.period";
|
||||
|
||||
/**
|
||||
* allowed PowerJob to invoke Thread#stop to kill a thread when PowerJob can't interrupt the thread
|
||||
* <a href="https://stackoverflow.com/questions/16504140/thread-stop-deprecated">It's VERY dangerous</a>
|
||||
*/
|
||||
public static final String WORKER_ALLOWED_FORCE_STOP_THREAD = "powerjob.worker.allowed-force-stop-thread";
|
||||
|
||||
public static final String WORKER_WORK_SPACE = "powerjob.worker.workspace";
|
||||
/**
|
||||
* ms
|
||||
*/
|
||||
public static final String FREQUENCY_JOB_MAX_INTERVAL = "powerjob.server.frequency-job.max-interval";
|
||||
|
||||
/* ******************* 不太可能有人用的参数,主要方便内部测试 ******************* */
|
||||
|
||||
/**
|
||||
* 最大活跃任务数量,超出部分 SWAP 到磁盘以提升性能
|
||||
*/
|
||||
public static final String WORKER_RUNTIME_SWAP_MAX_ACTIVE_TASK_NUM = "powerjob.worker.swap.max-active-task-num";
|
||||
|
||||
public static final String WORKER_RUNTIME_SWAP_TASK_SCHEDULE_INTERVAL_MS = "powerjob.worker.swap.scan-interval";
|
||||
|
||||
public static final String SERVER_TEST_ACCOUNT_USERNAME = "powerjob.server.test-accounts";
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package tech.powerjob.common;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* PowerJob Query interface
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2021/1/15
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class PowerQuery {
|
||||
|
||||
public static String EQUAL = "Eq";
|
||||
|
||||
public static String NOT_EQUAL = "NotEq";
|
||||
|
||||
public static String LIKE = "Like";
|
||||
|
||||
public static String NOT_LIKE = "NotLike";
|
||||
|
||||
public static String LESS_THAN = "Lt";
|
||||
|
||||
public static String LESS_THAN_EQUAL = "LtEq";
|
||||
|
||||
public static String GREATER_THAN = "Gt";
|
||||
|
||||
public static String GREATER_THAN_EQUAL = "GtEq";
|
||||
|
||||
public static String IN = "In";
|
||||
|
||||
public static String NOT_IN = "NotIn";
|
||||
|
||||
public static String IS_NULL = "IsNull";
|
||||
|
||||
public static String IS_NOT_NULL = "IsNotNull";
|
||||
|
||||
private Long appIdEq;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package tech.powerjob.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* PowerJob serializable interface.
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/16
|
||||
*/
|
||||
public interface PowerSerializable extends Serializable {
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package tech.powerjob.common;
|
||||
|
||||
/**
|
||||
* RemoteConstant
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/3/17
|
||||
*/
|
||||
public class RemoteConstant {
|
||||
|
||||
|
||||
/* ************************ AKKA WORKER ************************ */
|
||||
public static final int DEFAULT_WORKER_PORT = 27777;
|
||||
|
||||
|
||||
/* ************************ OTHERS ************************ */
|
||||
public static final String EMPTY_ADDRESS = "N/A";
|
||||
public static final long DEFAULT_TIMEOUT_MS = 5000;
|
||||
|
||||
/* ************************ SERVER-self_side (s4s == server for server side) ************************ */
|
||||
public static final String S4S_PATH = "friend";
|
||||
|
||||
/**
|
||||
* server 集群间的心跳处理
|
||||
*/
|
||||
public static final String S4S_HANDLER_PING = "ping";
|
||||
/**
|
||||
* 处理其他 server 的执行请求
|
||||
*/
|
||||
public static final String S4S_HANDLER_PROCESS = "process";
|
||||
|
||||
/* ************************ SERVER-worker_side(s4w == server for worker side) ************************ */
|
||||
public static final String S4W_PATH = "server";
|
||||
/**
|
||||
* server 处理在线日志
|
||||
*/
|
||||
public static final String S4W_HANDLER_REPORT_LOG = "reportLog";
|
||||
/**
|
||||
* server 处理 worker 心跳
|
||||
*/
|
||||
public static final String S4W_HANDLER_WORKER_HEARTBEAT = "workerHeartbeat";
|
||||
|
||||
/**
|
||||
* server 处理 TaskTracker 上报的任务实例状态
|
||||
*/
|
||||
public static final String S4W_HANDLER_REPORT_INSTANCE_STATUS = "reportInstanceStatus";
|
||||
|
||||
/**
|
||||
* server 查询任务的可执行集群
|
||||
*/
|
||||
public static final String S4W_HANDLER_QUERY_JOB_CLUSTER = "queryJobCluster";
|
||||
|
||||
/**
|
||||
* server 处理 worker 请求部署容器命令
|
||||
*/
|
||||
public static final String S4W_HANDLER_WORKER_NEED_DEPLOY_CONTAINER = "queryContainer";
|
||||
|
||||
/* ************************ Worker-TaskTracker ************************ */
|
||||
public static final String WTT_PATH = "taskTracker";
|
||||
|
||||
/**
|
||||
* server 任务执行命令
|
||||
*/
|
||||
public static final String WTT_HANDLER_RUN_JOB = "runJob";
|
||||
/**
|
||||
* server 停止任务实例命令
|
||||
*/
|
||||
public static final String WTT_HANDLER_STOP_INSTANCE = "stopInstance";
|
||||
|
||||
/**
|
||||
* sever 查询任务状态
|
||||
*/
|
||||
public static final String WTT_HANDLER_QUERY_INSTANCE_STATUS = "queryInstanceStatus";
|
||||
|
||||
/**
|
||||
* PT 上报任务状态,包含执行结果
|
||||
*/
|
||||
public static final String WTT_HANDLER_REPORT_TASK_STATUS = "reportTaskStatus";
|
||||
/**
|
||||
* PT 上报自身状态
|
||||
*/
|
||||
public static final String WTT_HANDLER_REPORT_PROCESSOR_TRACKER_STATUS = "reportProcessorTrackerStatus";
|
||||
|
||||
/**
|
||||
* Map 任务
|
||||
*/
|
||||
public static final String WTT_HANDLER_MAP_TASK = "mapTask";
|
||||
|
||||
/* ************************ Worker-ProcessorTracker ************************ */
|
||||
public static final String WPT_PATH = "processorTracker";
|
||||
|
||||
public static final String WPT_HANDLER_START_TASK = "startTask";
|
||||
|
||||
public static final String WPT_HANDLER_STOP_INSTANCE = "stopInstance";
|
||||
|
||||
/* ************************ Worker-NORMAL ************************ */
|
||||
|
||||
public static final String WORKER_PATH = "worker";
|
||||
|
||||
public static final String WORKER_HANDLER_DEPLOY_CONTAINER = "deployContainer";
|
||||
|
||||
public static final String WORKER_HANDLER_DESTROY_CONTAINER = "destroyContainer";
|
||||
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package tech.powerjob.common;
|
||||
|
||||
/**
|
||||
* 系统生成的任务实例运行结果
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/4/11
|
||||
*/
|
||||
public class SystemInstanceResult {
|
||||
|
||||
private SystemInstanceResult() {
|
||||
|
||||
}
|
||||
|
||||
/* *********** 普通instance 专用 *********** */
|
||||
|
||||
/**
|
||||
* 同时运行的任务实例数过多
|
||||
*/
|
||||
public static final String TOO_MANY_INSTANCES = "too many instances(%d>%d)";
|
||||
/**
|
||||
* 无可用worker
|
||||
*/
|
||||
public static final String NO_WORKER_AVAILABLE = "no worker available";
|
||||
/**
|
||||
* 任务执行超时
|
||||
*/
|
||||
public static final String INSTANCE_EXECUTE_TIMEOUT = "instance execute timeout";
|
||||
/**
|
||||
* 任务执行超时,成功打断任务
|
||||
*/
|
||||
public static final String INSTANCE_EXECUTE_TIMEOUT_INTERRUPTED = "instance execute timeout,interrupted success";
|
||||
/**
|
||||
* 任务执行超时,强制终止任务
|
||||
*/
|
||||
public static final String INSTANCE_EXECUTE_TIMEOUT_FORCE_STOP= "instance execute timeout,force stop success";
|
||||
|
||||
/**
|
||||
* 用户手动停止任务,成功打断任务
|
||||
*/
|
||||
public static final String USER_STOP_INSTANCE_INTERRUPTED= "user stop instance,interrupted success";
|
||||
/**
|
||||
* 用户手动停止任务,被系统强制终止
|
||||
*/
|
||||
public static final String USER_STOP_INSTANCE_FORCE_STOP= "user stop instance,force stop success";
|
||||
/**
|
||||
* 创建根任务失败
|
||||
*/
|
||||
public static final String TASK_INIT_FAILED = "create root task failed";
|
||||
/**
|
||||
* 未知错误
|
||||
*/
|
||||
public static final String UNKNOWN_BUG = "unknown bug";
|
||||
/**
|
||||
* TaskTracker 长时间未上报
|
||||
*/
|
||||
public static final String REPORT_TIMEOUT = "worker report timeout, maybe TaskTracker down";
|
||||
public static final String CAN_NOT_FIND_JOB_INFO = "can't find job info";
|
||||
|
||||
/* *********** workflow 专用 *********** */
|
||||
|
||||
public static final String MIDDLE_JOB_FAILED = "middle job failed";
|
||||
public static final String MIDDLE_JOB_STOPPED = "middle job stopped by user";
|
||||
public static final String CAN_NOT_FIND_JOB = "can't find some job";
|
||||
public static final String CAN_NOT_FIND_NODE = "can't find some node";
|
||||
public static final String ILLEGAL_NODE = "illegal node info";
|
||||
|
||||
/**
|
||||
* 没有启用的节点
|
||||
*/
|
||||
public static final String NO_ENABLED_NODES = "no enabled nodes";
|
||||
/**
|
||||
* 被用户手动停止
|
||||
*/
|
||||
public static final String STOPPED_BY_USER = "stopped by user";
|
||||
public static final String CANCELED_BY_USER = "canceled by user";
|
||||
|
||||
/**
|
||||
* 无效 DAG
|
||||
*/
|
||||
public static final String INVALID_DAG = "invalid dag";
|
||||
|
||||
/**
|
||||
* 被禁用的节点
|
||||
*/
|
||||
public static final String DISABLE_NODE = "disable node";
|
||||
/**
|
||||
* 标记为成功的节点
|
||||
*/
|
||||
public static final String MARK_AS_SUCCESSFUL_NODE = "mark as successful node";
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package tech.powerjob.common;
|
||||
|
||||
/**
|
||||
* 工作流上下文相关常量
|
||||
*
|
||||
* @author Echo009
|
||||
* @since 2021/2/3
|
||||
*/
|
||||
public final class WorkflowContextConstant {
|
||||
|
||||
/**
|
||||
* 上下文初始参数
|
||||
*/
|
||||
public static final String CONTEXT_INIT_PARAMS_KEY = "initParams";
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package tech.powerjob.common.enhance;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* 安全的 runnable,可防止因抛出异常导致周期性任务终止
|
||||
* 使用 {@link ScheduledExecutorService} 执行任务时,推荐继承此类捕获并打印异常,避免因为抛出异常导致周期性任务终止
|
||||
*
|
||||
* @author songyinyin
|
||||
* @since 2023/9/20 15:52
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class SafeRunnable implements Runnable{
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
run0();
|
||||
} catch (Exception e) {
|
||||
log.error("[SafeRunnable] run failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void run0();
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package tech.powerjob.common.enhance;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* 使用 {@link ScheduledExecutorService} 执行任务时,推荐使用此对象包装一层,避免因为抛出异常导致周期性任务终止
|
||||
*
|
||||
* @author songyinyin
|
||||
* @since 2023/9/20 16:04
|
||||
*/
|
||||
@Slf4j
|
||||
public class SafeRunnableWrapper implements Runnable {
|
||||
|
||||
private final Runnable runnable;
|
||||
|
||||
public SafeRunnableWrapper(Runnable runnable) {
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Exception e) {
|
||||
log.error("[SafeRunnableWrapper] run failed", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package tech.powerjob.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* DispatchStrategy
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2021/2/22
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DispatchStrategy {
|
||||
|
||||
/**
|
||||
* 健康度优先
|
||||
*/
|
||||
HEALTH_FIRST(1),
|
||||
/**
|
||||
* 随机
|
||||
*/
|
||||
RANDOM(2),
|
||||
/**
|
||||
* 指定执行
|
||||
*/
|
||||
SPECIFY(11)
|
||||
;
|
||||
|
||||
private final int v;
|
||||
|
||||
public static DispatchStrategy of(Integer v) {
|
||||
if (v == null) {
|
||||
return HEALTH_FIRST;
|
||||
}
|
||||
for (DispatchStrategy ds : values()) {
|
||||
if (v.equals(ds.v)) {
|
||||
return ds;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("unknown DispatchStrategy of " + v);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package tech.powerjob.common.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 加密类型
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2024/8/10
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum EncryptType {
|
||||
|
||||
NONE("none"),
|
||||
|
||||
MD5("md5")
|
||||
;
|
||||
|
||||
private final String code;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package tech.powerjob.common.enums;
|
||||
|
||||
/**
|
||||
* Environment Enum class.
|
||||
*
|
||||
* @author tjq
|
||||
* @since 2020/5/3
|
||||
*/
|
||||
public enum Env {
|
||||
/**
|
||||
* Development or test environment.
|
||||
*/
|
||||
DAILY,
|
||||
/**
|
||||
* Pre-release environment.
|
||||
*/
|
||||
PRE,
|
||||
/**
|
||||
* Production environment.
|
||||
*/
|
||||
PRODUCT
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user